NexusPi Git Node
lib/microReticulum/src/Transport.cpp 20ec0b4ee3f3e7a8b3c8d00dcdcd5afdcf2bc840 (20ec0b4e) Text, 171.74 KB
Tff7b72#Tff7b72include T8b949e"Transport.h"
Tff7b72#Tff7b72include T8b949e"Link.h"
Tff7b72#Tff7b72include T8b949e"Reticulum.h"
Tff7b72#Tff7b72include T8b949e"Destination.h"
Tff7b72#Tff7b72include T8b949e"Identity.h"
Tff7b72#Tff7b72include T8b949e"Packet.h"
Tff7b72#Tff7b72include T8b949e"Interface.h"
Tff7b72#Tff7b72include T8b949e"Log.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/Random.h"
Tff7b72#Tff7b72include T8b949e"Cryptography/HKDF.h"
Tff7b72#Tff7b72include T8b949e"Utilities/OS.h"
Tff7b72#Tff7b72include T8b949e"Utilities/Persistence.h"
Tff7b72#Tff7b72include T8b949e<algorithm>
Tff7b72#Tff7b72include T8b949e<unistd.h>
Tff7b72#Tff7b72include T8b949e<time.h>
Tff7b72using Tff7b72namespace T7ee787RNSTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787TypeTff7b72:Tff7b72:T7ee787TransportTb4b4b4;
Tff7b72using Tff7b72namespace T7ee787RNSTff7b72:Tff7b72:T7ee787UtilitiesTb4b4b4;
T8b949e// ── Flat-map helpers (vector<pair<Bytes,T>> replaces std::map<Bytes,T>) ────
T8b949e// Eliminates per-element tree-node allocation. Linear search is fine
T8b949e// for N ≤ ~1000 on ESP32.
Tff7b72template Tff7b72<Tff7b72typename T56d364TTff7b72>
Tff7b72static Tff7b72typename T56d364stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72:Tff7b72:Te6edf3iterator
Te6edf3flatmap_findTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3it Tff7b72= Te6edf3vecTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3it Tff7b72!Tff7b72= Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72+Tff7b72+Te6edf3itTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3itTff7b72-Tff7b72>Te6edf3first Tff7b72=Tff7b72= Te6edf3keyTb4b4b4) Tff7b72return Te6edf3itTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72template Tff7b72<Tff7b72typename T56d364TTff7b72>
Tff7b72static Tff7b72typename T56d364stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72:Tff7b72:Te6edf3const_iterator
Te6edf3flatmap_findTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3it Tff7b72= Te6edf3vecTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3it Tff7b72!Tff7b72= Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72+Tff7b72+Te6edf3itTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3itTff7b72-Tff7b72>Te6edf3first Tff7b72=Tff7b72= Te6edf3keyTb4b4b4) Tff7b72return Te6edf3itTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72template Tff7b72<Tff7b72typename T56d364TTff7b72>
Tff7b72static Tffa657void Te6edf3flatmap_upsertTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4, Tff7b72const Te6edf3TTff7b72& Te6edf3valueTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3it Tff7b72= Te6edf3flatmap_findTb4b4b4(Te6edf3vecTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3it Tff7b72!Tff7b72= Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3itTff7b72-Tff7b72>Te6edf3second Tff7b72= Te6edf3valueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3vecTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3keyTb4b4b4, Te6edf3valueTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72template Tff7b72<Tff7b72typename T56d364TTff7b72>
Tff7b72static Tffa657bool Te6edf3flatmap_eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TTff7b72>Tff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3it Tff7b72= Te6edf3flatmap_findTb4b4b4(Te6edf3vecTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3it Tff7b72!Tff7b72= Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3vecTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3itTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// ── Flat-set helpers (vector<Bytes> replaces std::set<Bytes>) ──────────────
Tff7b72static Tffa657bool Te6edf3flatset_containsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3vecTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3keyTb4b4b4) Tff7b72!Tff7b72= Te6edf3vecTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72static Tffa657void Te6edf3flatset_insertTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3vecTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3keyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3flatset_containsTb4b4b4(Te6edf3vecTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3vecTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3keyTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72if defined(INTERFACES_SET)
T8b949e///*static*/ std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> Transport::_interfaces;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3reference_wrapperTff7b72<Te6edf3InterfaceTff7b72>Tb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3lessTff7b72<Te6edf3InterfaceTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3reference_wrapperTff7b72<Te6edf3InterfaceTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3InterfaceTff7b72&Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_interfacesTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinationsTb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinationsTb4b4b4;
Tff7b72#Tff7b72endif
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_pending_linksTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_active_linksTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packet_hashlistTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_global_blobsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receiptsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3AnnounceEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3dequeTff7b72<Te6edf3TransportTff7b72:Tff7b72:Te6edf3PathEntryTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destination_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3ReverseEntryTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_reverse_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3LinkEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_link_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3AnnounceEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_held_announcesTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3HAnnounceHandlerTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_handlersTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3TunnelEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tunnelsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3RateEntryTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announce_rate_tableTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_requestsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Te6edf3TransportTff7b72:Tff7b72:Te6edf3PathRequestEntryTff7b72>Tff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_discovery_path_requestsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_discovery_pr_tagsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3DestinationTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_control_destinationsTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_control_hashesTb4b4b4;
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3BytesTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3_pending_local_path_requestsTb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_start_time Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_job_interval Tff7b72= T79c0ff0.250Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_jobs_last_run Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_links_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_links_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receipts_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_receipts_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announces_last_checked Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_announces_check_interval Tff7b72= T79c0ff1.0Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tables_last_culled Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//float Transport::_tables_cull_interval = 5.0;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_tables_cull_interval Tff7b72= T79c0ff60.0Tb4b4b4;
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3_saving_path_table Tff7b72= Tffa657falseTb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//uint16_t Transport::_hashlist_maxsize = 1000000;
T8b949e/*static*/ T8b949e//uint16_t Transport::_hashlist_maxsize = 100;
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_hashlist_maxsize Tff7b72= T79c0ff100Tb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e// CBA MCU
T8b949e/*static*/ T8b949e//uint16_t Transport::_max_pr_tags = 32000;
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_max_pr_tags Tff7b72= T79c0ff32Tb4b4b4;
T8b949e// CBA
T8b949e// CBA ACCUMULATES
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_table_maxsize Tff7b72= T79c0ff100Tb4b4b4;
T8b949e// CBA ACCUMULATES
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_path_table_maxpersist Tff7b72= T79c0ff100Tb4b4b4;
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_saved Tff7b72= T79c0ff0.0Tb4b4b4;
T8b949e/*static*/ Tffa657float Te6edf3TransportTff7b72:Tff7b72:Te6edf3_save_interval Tff7b72= T79c0ff3600.0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destination_table_crc Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Te6edf3Reticulum Td2a8ffTransport::_ownerTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE Whitelist 1: addresses of local devices (from LoRa and LocalTCP interfaces)
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3_firewall_local_addressesTb4b4b4;
T8b949e// FIREWALL MODE Whitelist 2: addresses mentioned in packets from local devices
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3_firewall_mentioned_addressesTb4b4b4;
Tff7b72static Tff7b72const Tffa657uint16_t Te6edf3_firewall_maxsize Tff7b72= T79c0ff200Tb4b4b4;
T8b949e// ── Whitelist helpers: enforce uniqueness on push (no per-node alloc) ──
Tff7b72static Tffa657void Td2a8ffwl1_pushTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3addrTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3addrTb4b4b4) Tff7b72returnTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3addrTb4b4b4)
Tff7b72=Tff7b72= Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3addrTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72static Tffa657bool Td2a8ffwl2_pushTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3addrTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3addrTb4b4b4) Tff7b72return Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3addrTb4b4b4)
Tff7b72=Tff7b72= Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// ── Watched-destination logging ────────────────────────────────────────
T8b949e// Define WATCH_LOG to only log packets touching specific named destinations.
T8b949e// Comment out to restore full logging.
Tff7b72#Tff7b72define WATCH_LOG
Tff7b72#Tff7b72ifdef WATCH_LOG
Tff7b72struct T56d364WatchedDest Tb4b4b4{
Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4;
Te6edf3Bytes Te6edf3hashTb4b4b4;
Tb4b4b4}Tb4b4b4;
Tff7b72static Tff7b72const Te6edf3WatchedDest Te6edf3_watchedTb4b4b4[Tb4b4b4] Tff7b72= Tb4b4b4{
Tb4b4b4{Ta5d6ff"Ta5d6ffMeshchatTa5d6ff"Tb4b4b4, Te6edf3BytesTb4b4b4(Ta5d6ff"Tffea00\x13Tffea00\xf4Tffea00\xb1Tffea00\x4dTffea00\xd3Tffea00\x64Tffea00\xa6Tffea00\x72Tffea00\xe8Tffea00\x53Tffea00\xa3Tffea00\x7fTffea00\xb5Tffea00\x34Tffea00\x67Tffea00\x8cTa5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Tb4b4b4{Ta5d6ff"Ta5d6ffSidebandTa5d6ff"Tb4b4b4, Te6edf3BytesTb4b4b4(Ta5d6ff"Tffea00\x29Tffea00\xf9Tffea00\xa2Tffea00\x0cTffea00\xb0Tffea00\x47Tffea00\x60Tffea00\xedTffea00\xbcTffea00\x49Tffea00\x7dTffea00\x66Tffea00\x8cTffea00\x25Tffea00\x5aTffea00\xb7Ta5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Tb4b4b4{Ta5d6ff"Ta5d6ffBrowserTa5d6ff"Tb4b4b4, Te6edf3BytesTb4b4b4(Ta5d6ff"Tffea00\x03Tffea00\x58Tffea00\x19Tffea00\x2fTffea00\x7bTffea00\x88Tffea00\xb0Tffea00\x78Tffea00\x68Tffea00\xe8Tffea00\xd8Tffea00\x32Tffea00\xceTffea00\xa5Tffea00\x1bTffea00\x7eTa5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
T8b949e// Populated at runtime: ratchet hashes and link IDs → parent destination name
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Tff7b72const Tffa657charTff7b72*Tff7b72> Te6edf3_watch_aliasesTb4b4b4;
Tff7b72static Tffa657void Td2a8ffwatch_add_aliasTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3aliasTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3alias Tff7b72&Tff7b72& Te6edf3_watch_aliasesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3aliasTb4b4b4) Tff7b72=Tff7b72= Te6edf3_watch_aliasesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_watch_aliasesTb4b4b4[Te6edf3aliasTb4b4b4] Tff7b72= Te6edf3nameTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72static Tff7b72const Tffa657charTff7b72* Td2a8ffwatch_resolveTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3addrTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3addrTb4b4b4) Tff7b72return Tffa657nullptrTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3w Tff7b72: Te6edf3_watchedTb4b4b4) Tff7b72if Tb4b4b4(Te6edf3addr Tff7b72=Tff7b72= Te6edf3wTb4b4b4.Te6edf3hashTb4b4b4) Tff7b72return Te6edf3wTb4b4b4.Te6edf3nameTb4b4b4;
Tff7b72auto Te6edf3it Tff7b72= Te6edf3_watch_aliasesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3addrTb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3it Tff7b72!Tff7b72= Te6edf3_watch_aliasesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72? Te6edf3itTff7b72-Tff7b72>Te6edf3second Tff7b72: Tffa657nullptrTb4b4b4;
Tb4b4b4}
T8b949e// Check if a packet touches any watched destination; return name if so.
Tff7b72static Tff7b72const Tffa657charTff7b72* Td2a8ffwatch_matchTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72const Tffa657charTff7b72* Te6edf3nTb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3n Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3nTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3lid Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3n Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3lidTb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3n Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3FLAG_SET
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff116Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3rh Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff84Tb4b4b4, T79c0ff32Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3n Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3rhTb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tb4b4b4(Te6edf3n Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3nTb4b4b4;
Tff7b72return Tffa657nullptrTb4b4b4;
Tb4b4b4}
T8b949e// Helper: human-readable zone tag
Tff7b72static Tff7b72inline Tff7b72const Tffa657charTff7b72* Td2a8ffzone_tagTb4b4b4(Tffa657bool Te6edf3is_backboneTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3is_backbone Tff7b72? Ta5d6ff"Ta5d6ffWANTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffLANTa5d6ff"Tb4b4b4;
Tb4b4b4}
T8b949e// Helper: short hash for logging
Tff7b72static Te6edf3stdTff7b72:Tff7b72:Te6edf3string Td2a8ffshort_hashTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3hTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3hTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffnoneTa5d6ff"Tb4b4b4;
Tff7b72return Te6edf3hTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72define WLOG(pkt, msg) do { \
Tff7b72 const char* _wn = watch_match(pkt); \
Tff7b72 if (_wn) { \
Tff7b72 Interface _rif = pkt.receiving_interface(); \
Tff7b72 bool _from_bb = _rif && is_backbone_interface(_rif); \
Tff7b72 Serial.print("["); Serial.print(_wn); Serial.print("] "); \
Tff7b72 Serial.printf("[%s] - FROM: %s (%s) - %s\n", \
Tff7b72 pkt_type_name(pkt.packet_type()), \
Tff7b72 _rif ? _rif.toString().c_str() : "?", \
Tff7b72 zone_tag(_from_bb), \
Tff7b72 std::string(msg).c_str()); \
Tff7b72 } \
Tff7b72} while(0)
Tff7b72#Tff7b72else
Tff7b72#Tff7b72define WLOG(fmt, ...) do {} while(0)
Tff7b72#Tff7b72endif
T8b949e// FIREWALL MODE: Check if an interface is the backbone
Tff7b72static Tffa657bool Td2a8ffis_backbone_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3ifaceTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3ifaceTb4b4b4.Te6edf3is_backboneTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Human-readable packet type abbreviations
Tff7b72static Tff7b72const Tffa657charTff7b72* Td2a8ffpkt_type_nameTb4b4b4(Tffa657uint8_t Te6edf3tTb4b4b4) Tb4b4b4{
Tff7b72switch Tb4b4b4(Te6edf3tTb4b4b4) Tb4b4b4{
Tff7b72case T79c0ff0Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffDATATa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff1Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffANNCTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff2Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffLREQTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff3Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffPROOFTa5d6ff"Tb4b4b4;
Tff7b72defaultTff7b72: Tff7b72return Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Human-readable context name for resource tracing
Tff7b72static Tff7b72const Tffa657charTff7b72* Td2a8ffctx_nameTb4b4b4(Tffa657uint8_t Te6edf3ctxTb4b4b4) Tb4b4b4{
Tff7b72switch Tb4b4b4(Te6edf3ctxTb4b4b4) Tb4b4b4{
Tff7b72case T79c0ff0x01Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCETa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x02Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_ADVTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x03Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_REQTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x04Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_HMUTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x05Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_PRFTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x06Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_ICLTa5d6ff"Tb4b4b4;
Tff7b72case T79c0ff0x07Tb4b4b4: Tff7b72return Ta5d6ff"Ta5d6ffRESOURCE_RCLTa5d6ff"Tb4b4b4;
Tff7b72defaultTff7b72: Tff7b72return Tffa657nullptrTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72static Tff7b72inline Tffa657bool Td2a8ffis_resource_ctxTb4b4b4(Tffa657uint8_t Te6edf3ctxTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3ctx Tff7b72>Tff7b72= T79c0ff0x01 Tff7b72&Tff7b72& Te6edf3ctx Tff7b72<Tff7b72= T79c0ff0x07Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Te6edf3Identity Td2a8ffTransport::_identityTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// CBA
T8b949e/*static*/ Te6edf3TransportTff7b72:Tff7b72:Te6edf3Callbacks Te6edf3TransportTff7b72:Tff7b72:Te6edf3_callbacksTb4b4b4;
T8b949e// CBA Stats
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packets_sent Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_packets_received Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_destinations_added Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657size_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_memory Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657size_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3_last_flash Tff7b72= T79c0ff0Tb4b4b4;
T8b949e/*static*/ Tffa657void Td2a8ffTransport::startTb4b4b4(Tff7b72const Te6edf3ReticulumTff7b72& Te6edf3reticulum_instanceTb4b4b4) Tb4b4b4{
Te6edf3INFOTb4b4b4(Ta5d6ff"Ta5d6ffTransport starting...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657trueTb4b4b4;
Te6edf3_owner Tff7b72= Te6edf3reticulum_instanceTb4b4b4;
T8b949e// Initialize time-based variables *after* time offset update
Te6edf3_jobs_last_run Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_links_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_receipts_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_announces_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_tables_last_culled Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_last_saved Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// ensure required directories exist
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3OSTff7b72:Tff7b72:Te6edf3directory_existsTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffNo cache directory, creating...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3OSTff7b72:Tff7b72:Te6edf3create_directoryTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3HEADTb4b4b4(Ta5d6ff"Ta5d6ffFailed to create cache directory — packet cache will be unavailableTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72:Tff7b72:Te6edf3LOG_CRITICALTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Tffa657char Te6edf3transport_identity_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3transport_identity_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/transport_identityTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffChecking for transport identity...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_identity Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3from_fileTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffNo valid Transport Identity in storage, creating...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_identity Tff7b72= Te6edf3IdentityTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_identityTb4b4b4.Te6edf3to_fileTb4b4b4(Te6edf3transport_identity_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffLoaded Transport Identity from storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffFailed to check for transport identity, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// TODO
T8b949e/*
packet_hashlist_path = Reticulum::storagepath + "/packet_hashlist";
if (!owner.is_connected_to_shared_instance()) {
if (os.path.isfile(packet_hashlist_path)) {
try {
}
catch (std::exception& e) {
ERRORF("Could not load packet hashlist from storage, the contained exception was: %s", e.what());
}
}
}
*/
T8b949e// Create transport-specific destination for path request
Te6edf3Destination Te6edf3path_request_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpath.requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_destinationTb4b4b4.Te6edf3set_packet_callbackTb4b4b4(Te6edf3path_request_handlerTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3path_request_destinationTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3path_request_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffPATH-REQ-DST: Ta5d6ff" Tff7b72+ Te6edf3path_request_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff — path requests to this hash will seed whitelistTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Create transport-specific destination for tunnel synthesize
Te6edf3Destination Te6edf3tunnel_synthesize_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6fftunnel.synthesizeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3set_packet_callbackTb4b4b4(Te6edf3tunnel_synthesize_handlerTb4b4b4)Tb4b4b4;
T8b949e// CBA BUG?
T8b949e// CBA ACCUMULATES
Te6edf3_control_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3tunnel_synthesize_destinationTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_control_hashesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCreated transport-specific tunnel synthesize destination Ta5d6ff" Tff7b72+ Te6edf3tunnel_synthesize_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e// CBA Threading
Tff7b72if Tb4b4b4(Tffa657trueTb4b4b4) Tb4b4b4{
Te6edf3INFOTb4b4b4(Ta5d6ff"Ta5d6ffTransport mode is enabledTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Read in path table and then write and clean in case any entries are invalid
Te6edf3read_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffWriting path table and cleaning caches to clean-up any orphaned paths/filesTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3write_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3clean_cachesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3read_tunnel_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Create transport-specific destination for probe requests
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3probe_destination_enabledTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3Destination Te6edf3probe_destinationTb4b4b4(Te6edf3_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffprobeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3accepts_linksTb4b4b4(Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3set_proof_strategyTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_ALLTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCreated probe responder destination Ta5d6ff" Tff7b72+ Te6edf3probe_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3probe_destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffTransport Instance will respond to probe requests on Ta5d6ff" Tff7b72+ Te6edf3probe_destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3VERBOSETb4b4b4(Ta5d6ff"Ta5d6ffTransport instance Ta5d6ff" Tff7b72+ Te6edf3_identityTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff startedTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_start_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// TODO
T8b949e//#ifndef NDEBUG
T8b949e// CBA DEBUG
Te6edf3dump_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//#endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_jobs_last_run Tff7b72+ Te6edf3_job_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3jobsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_jobs_last_run Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::jobsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e//TRACE("Transport::jobs()");
T8b949e// Heap telemetry: snapshot at jobs entry
Tffa657size_t Te6edf3_jobs_heap_entry Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3PacketTff7b72> Te6edf3outgoingTb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72> Te6edf3path_requestsTb4b4b4;
Tffa657int Te6edf3countTb4b4b4;
Te6edf3_jobs_running Tff7b72= Tffa657trueTb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_jobs_lockedTb4b4b4) Tb4b4b4{
T8b949e// Process active and pending link lists
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_links_last_checked Tff7b72+ Te6edf3_links_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3pending_linksTb4b4b4(Te6edf3_pending_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3pending_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
T8b949e// If we are not a Transport Instance, finding a pending link
T8b949e// that was never activated will trigger removal of the path
T8b949e// via the link's interface, leaving backup paths intact.
Tff7b72if Tb4b4b4(Tffa657falseTb4b4b4) Tb4b4b4{
T8b949e// Remove only the path on the failed link's interface,
T8b949e// so other paths (e.g. LoRa) survive the failure.
Te6edf3Interface Te6edf3failed_iface Tff7b72= Te6edf3linkTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3failed_ifaceTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemoving path to Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff via Ta5d6ff" Tff7b72+ Te6edf3failed_ifaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (link closed, backup paths survive)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3mark_path_unresponsiveTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3failed_ifaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3expire_pathTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// If we are connected to a shared instance, it will take
T8b949e// care of sending out a new path request. If not, we will
T8b949e// send one directly.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657double Te6edf3last_path_request Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3flatmap_findTb4b4b4(Te6edf3_path_requestsTb4b4b4, Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3last_path_request Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_path_requestTb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_MITb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never establishedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//if (path_requests.find(link.destination().hash()) == path_requests.end()) {
Tff7b72if Tb4b4b4(Te6edf3path_requestsTb4b4b4.Te6edf3countTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3_pending_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
Te6edf3_active_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3_links_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Process receipts list for timed-out packets
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_receipts_last_checked Tff7b72+ Te6edf3_receipts_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Te6edf3_receiptsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3MAX_RECEIPTSTb4b4b4) Tb4b4b4{
Te6edf3PacketReceipt Te6edf3culled_receipt Tff7b72= Te6edf3_receiptsTb4b4b4.Te6edf3frontTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_receiptsTb4b4b4.Te6edf3pop_frontTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3culled_receiptTb4b4b4.Te6edf3set_timeoutTb4b4b4(T79c0ff-1Tb4b4b4)Tb4b4b4;
Te6edf3culled_receiptTb4b4b4.Te6edf3check_timeoutTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3cull_receiptsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3receiptTb4b4b4.Te6edf3check_timeoutTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3receiptTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3SENTTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA since modifying of collection while iterating is forbidden
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_receipts_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Process announces needing retransmission
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_announces_last_checked Tff7b72+ Te6edf3_announces_check_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-TBL size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3announce_entryTb4b4b4] Tff7b72: Te6edf3_announce_tableTb4b4b4) Tb4b4b4{
T8b949e//for (auto& pair : _announce_table) {
T8b949e// const auto& destination_hash = pair.first;
T8b949e// auto& announce_entry = pair.second;
T8b949e//TRACE("[0] announce entry data size: " + std::to_string(announce_entry._packet.data().size()));
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-ENTRY dest=Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff retries=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retriesTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff block=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timeout_in=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeout Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3LOCAL_REBROADCASTS_MAXTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCompleted announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, local rebroadcast limit reachedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA OK to modify collection here since we're immediately exiting iteration
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-CULL dest=Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff retries=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_retriesTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff reason=retry_limitTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCompleted announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff, retry limit reachedTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA OK to modify collection here since we're immediately exiting iteration
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeoutTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffPerforming announce processing for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_retransmit_timeout Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_G Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RWTb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3context_types Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tb4b4b4{
Te6edf3announce_context Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4;
Tb4b4b4}
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//Destination announce_destination(announce_identity, Type::Destination::OUT, Type::Destination::SINGLE, "unknown", "unknown");
T8b949e//announce_destination.hash(announce_entry._packet.destination_hash());
Te6edf3Destination Te6edf3announce_destinationTb4b4b4(Te6edf3announce_identityTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4, Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//P announce_destination.hexhash = announce_destination.hash.hex()
T8b949e//if (announce_entry._attached_interface) {
T8b949e//TRACE("[1] interface is valid");
T8b949e//TRACE("[1] interface: " + announce_entry._attached_interface.debugString());
T8b949e//TRACE("[1] interface: " + announce_entry._attached_interface.toString());
T8b949e//}
Te6edf3Packet Te6edf3new_packetTb4b4b4(
Te6edf3announce_destinationTb4b4b4,
T8b949e//{Type::NONE},
Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interfaceTb4b4b4,
T8b949e//{Type::NONE},
Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4,
Te6edf3announce_contextTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4,
Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4,
Te6edf3TransportTff7b72:Tff7b72:Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657trueTb4b4b4,
Te6edf3announce_entryTb4b4b4.Te6edf3_packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_hopsTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_block_rebroadcastsTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasting announce as path response for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with hop count Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: SENDING PATH-RESP announce for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff attached=Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interface Tff7b72? Te6edf3announce_entryTb4b4b4.Te6edf3_attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ffNONETa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasting announce for Ta5d6ff" Tff7b72+ Te6edf3announce_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with hop count Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3outgoingTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3new_packetTb4b4b4)Tb4b4b4;
T8b949e// This handles an edge case where a peer sends a past
T8b949e// request for a destination just after an announce for
T8b949e// said destination has arrived, but before it has been
T8b949e// rebroadcast locally. In such a case the actual announce
T8b949e// is temporarily held, and then reinserted when the path
T8b949e// request has been served to the peer.
Tff7b72auto Te6edf3iter Tff7b72=Te6edf3_held_announcesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3held_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
T8b949e//_announce_table[destination_hash] = held_entry;
T8b949e//_announce_table.insert_or_assign({destination_hash, held_entry});
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Te6edf3held_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffReinserting held announce into tableTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA Must break after erase to avoid iterator invalidation
T8b949e// (same pattern as the other two erases above in this loop)
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3_announces_last_checked Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Cull held announces that are older than 60 seconds or if map exceeds cap
Tb4b4b4{
Tff7b72const Tffa657double Te6edf3held_timeout Tff7b72= T79c0ff60.0Tb4b4b4;
Tff7b72const Tffa657uint16_t Te6edf3held_maxsize Tff7b72= T79c0ff32Tb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3held_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCulling expired held announce for Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3iter Tff7b72= Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72+Tff7b72+Te6edf3iterTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72while Tb4b4b4(Te6edf3_held_announcesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3held_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffCulling oldest held announce (cap Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3held_maxsizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_held_announcesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_held_announcesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the packet hashlist if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_hashlist_maxsizeTb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3excess Tff7b72= Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_hashlist_maxsizeTb4b4b4;
Te6edf3_packet_hashlistTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3excessTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Cull the firewall mentioned addresses if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_firewall_maxsizeTb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3excess Tff7b72= Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_firewall_maxsizeTb4b4b4;
Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3excessTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Cull the firewall local addresses if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_firewall_maxsizeTb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3excess Tff7b72= Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_firewall_maxsizeTb4b4b4;
Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3excessTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Cull the path request tags list if it has reached its max size
Tff7b72if Tb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_max_pr_tagsTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3BytesTff7b72>Tff7b72:Tff7b72:Te6edf3iterator Te6edf3iter Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3advanceTb4b4b4(Te6edf3iterTb4b4b4, Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3_max_pr_tagsTb4b4b4)Tb4b4b4;
Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3_tables_last_culled Tff7b72+ Te6edf3_tables_cull_intervalTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA Disabled following since we're calling immediately after adding to path table now
T8b949e// Cull the path table if it has reached its max size
T8b949e//cull_path_table();
T8b949e// Cull the reverse table according to timeout
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_reverse_entriesTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3packet_hashTb4b4b4, Te6edf3reverse_entryTb4b4b4] Tff7b72: Te6edf3_reverse_tableTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3REVERSE_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_reverse_entriesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the link table according to timeout
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_linksTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3link_idTb4b4b4, Te6edf3link_entryTb4b4b4] Tff7b72: Te6edf3_link_tableTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_validatedTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3LINK_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_linksTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3link_entryTb4b4b4.Te6edf3_proof_timeoutTb4b4b4) Tb4b4b4{
Te6edf3stale_linksTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3last_path_request Tff7b72= T79c0ff0.0Tb4b4b4;
Tff7b72const Tff7b72autoTff7b72& Te6edf3iter Tff7b72= Te6edf3flatmap_findTb4b4b4(Te6edf3_path_requestsTb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3last_path_request Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3lr_taken_hops Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4;
Tffa657bool Te6edf3path_request_throttle Tff7b72= Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_path_requestTb4b4b4) Tff7b72< Te6edf3PATH_REQUEST_MITb4b4b4;
Tffa657bool Te6edf3path_request_conditions Tff7b72= Tffa657falseTb4b4b4;
T8b949e// If the path has been invalidated between the time of
T8b949e// making the link request and now, try to rediscover it
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3has_pathTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and path is now missingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If this link request was originated from a local client
T8b949e// attempt to rediscover a path to the destination, if this
T8b949e// has not already happened recently.
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3path_request_throttle Tff7b72&Tff7b72& Te6edf3lr_taken_hops Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted local client link was never establishedTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If the link destination was previously only 1 hop
T8b949e// away, this likely means that it was local to one
T8b949e// of our interfaces, and that it roamed somewhere else.
T8b949e// In that case, try to discover a new path.
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3path_request_throttle Tff7b72&Tff7b72& Te6edf3hops_toTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and destination was previously local to an interface on this instanceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// If the link destination was previously only 1 hop
T8b949e// away, this likely means that it was local to one
T8b949e// of our interfaces, and that it roamed somewhere else.
T8b949e// In that case, try to discover a new path.
Tff7b72else Tff7b72if Tb4b4b4( Tff7b72!Te6edf3path_request_throttle Tff7b72and Te6edf3lr_taken_hops Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTrying to rediscover path for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since an attempted link was never established, and link initiator is local to an interface on this instanceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3path_request_conditions Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3path_request_conditionsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3path_requestsTb4b4b4.Te6edf3countTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tffa657falseTb4b4b4) Tb4b4b4{
T8b949e// Remove the failed outbound interface's path,
T8b949e// leaving backup paths (e.g. LoRa) intact so
T8b949e// select_path() falls through naturally.
Tff7b72if Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemoving path to Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff via Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (link establishment failed, backup paths survive)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3mark_path_unresponsiveTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4, Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3expire_pathTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the path table: remove expired entries and empty deques
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_pathsTb4b4b4;
Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
T8b949e// Remove expired individual entries
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Te6edf3nowTb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3eTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4,
Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Remove entries whose interface no longer exists
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3eTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72!Te6edf3ifaceTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_pathsTb4b4b4) Tb4b4b4{
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the pending discovery path requests table
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_discovery_path_requestsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3path_entryTb4b4b4] Tff7b72: Te6edf3_discovery_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3path_entryTb4b4b4.Te6edf3_timeoutTb4b4b4) Tb4b4b4{
Te6edf3stale_discovery_path_requestsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffDISCOVERY-EXPIRED: path request for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out after Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_TIMEOUTTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ffsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the path requests table (entries only needed for PATH_REQUEST_MI throttling, 20s)
Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_path_requestsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3timestampTb4b4b4] Tff7b72: Te6edf3_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3timestamp Tff7b72+ Te6edf3PATH_REQUEST_MI Tff7b72* T79c0ff2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_path_requestsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_path_requestsTb4b4b4) Tb4b4b4{
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_path_requestsTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull pending local path requests for interfaces that no longer exist
Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_plprTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3iface_hashTb4b4b4] Tff7b72: Te6edf3_pending_local_path_requestsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_interfacesTb4b4b4.Te6edf3countTb4b4b4(Te6edf3iface_hashTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3stale_plprTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_plprTb4b4b4) Tb4b4b4{
Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Cull the tunnel table
Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_tunnelsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3tunnel_idTb4b4b4, Te6edf3tunnel_entryTb4b4b4] Tff7b72: Te6edf3_tunnelsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3tunnel_entryTb4b4b4.Te6edf3_expiresTb4b4b4) Tb4b4b4{
Te6edf3stale_tunnelsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3tunnel_idTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTunnel Ta5d6ff" Tff7b72+ Te6edf3tunnel_idTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3stale_tunnel_pathsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destination_entryTb4b4b4] Tff7b72: Te6edf3tunnel_entryTb4b4b4.Te6edf3_serialised_pathsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3destination_entryTb4b4b4.Te6edf3_timestamp Tff7b72+ Te6edf3DESTINATION_TIMEOUTTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3stale_tunnel_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTunnel path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff timed out and was removedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//for (const auto& destination_hash : stale_tunnel_paths) {
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3stale_tunnel_pathsTb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3TunnelEntryTff7b72&Tff7b72>Tb4b4b4(Te6edf3tunnel_entryTb4b4b4)Tb4b4b4.Te6edf3_serialised_pathsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3countTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff tunnel pathsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3remove_reverse_entriesTb4b4b4(Te6edf3stale_reverse_entriesTb4b4b4)Tb4b4b4;
Te6edf3remove_linksTb4b4b4(Te6edf3stale_linksTb4b4b4)Tb4b4b4;
Te6edf3remove_pathsTb4b4b4(Te6edf3stale_pathsTb4b4b4)Tb4b4b4;
Te6edf3remove_discovery_path_requestsTb4b4b4(Te6edf3stale_discovery_path_requestsTb4b4b4)Tb4b4b4;
Te6edf3remove_tunnelsTb4b4b4(Te6edf3stale_tunnelsTb4b4b4)Tb4b4b4;
T8b949e//#ifndef NDEBUG
Te6edf3dump_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//#endif
Te6edf3_tables_last_culled Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA Periodically persist data
T8b949e//if (OS::time() > (_last_saved + _save_interval)) {
T8b949e// persist_data();
T8b949e// _last_saved = OS::time();
T8b949e//}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Transport jobs were locked, do nothing
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAn exception occurred while running Transport jobs.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_running Tff7b72= Tffa657falseTb4b4b4;
T8b949e// Heap telemetry: snapshot at jobs exit (MUTED)
T8b949e// {
T8b949e// size_t _jobs_heap_exit = OS::heap_available();
T8b949e// int _jobs_delta = (int)_jobs_heap_exit - (int)_jobs_heap_entry;
T8b949e// if (_jobs_delta < -64 || _jobs_delta > 64) {
T8b949e// VERBOSEF("[HEAP-TEL] jobs: %d bytes (heap=%u)", _jobs_delta, (uint32_t)_jobs_heap_exit);
T8b949e// }
T8b949e// }
T8b949e// CBA send announce retransmission packets
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3packet Tff7b72: Te6edf3outgoingTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: OUTGOING announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff attached=Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4) Tff7b72? Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ffNONETa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA send link-related path requests
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3path_requestsTb4b4b4) Tb4b4b4{
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Td2a8ffTransport::transmitTb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3rawTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::transmit()Ta5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_transmit_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_callbacksTb4b4b4.Te6edf3_transmit_packetTb4b4b4(Te6edf3rawTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing transmit packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72try Tb4b4b4{
T8b949e//if hasattr(interface, "ifac_identity") and interface.ifac_identity != None:
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Calculate packet access code by signing the raw packet
T8b949e// and taking the last ifac_size bytes of the signature
Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3ifac_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3signTb4b4b4(Te6edf3rawTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3ifac Tff7b72= Te6edf3signatureTb4b4b4.Te6edf3rightTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Generate mask via HKDF
Te6edf3Bytes Te6edf3mask Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3ifacTb4b4b4,
Te6edf3interfaceTb4b4b4.Te6edf3ifac_keyTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// Set IFAC flag in header byte 0
Tffa657uint8_t Te6edf3new_header0 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72| T79c0ff0x80Tb4b4b4;
Tffa657uint8_t Te6edf3new_header1 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
T8b949e// Assemble new payload: new_header + ifac + raw[2:]
Te6edf3Bytes Te6edf3new_rawTb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header0Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header1Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3ifacTb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Mask payload
Te6edf3Bytes Te6edf3masked_rawTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Mask first header byte, keep IFAC flag set
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Tb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4) Tff7b72| T79c0ff0x80Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3i Tff7b72=Tff7b72= T79c0ff1 Tff7b72|Tff7b72| Te6edf3i Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Mask second header byte and payload
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Don't mask the IFAC itself
Te6edf3masked_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_rawTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Send it
Te6edf3interfaceTb4b4b4.Te6edf3send_outgoingTb4b4b4(Te6edf3masked_rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3interfaceTb4b4b4.Te6edf3send_outgoingTb4b4b4(Te6edf3rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while transmitting on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Td2a8ffTransport::outboundTb4b4b4(Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3_packets_sentTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//throw std::invalid_argument("Can not send packet with no destination.");
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffCan not send packet with no destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: destination=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_jobs_runningTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: sleeping...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(T79c0ff0.0005Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657trueTb4b4b4;
Tffa657bool Te6edf3sent Tff7b72= Tffa657falseTb4b4b4;
Tffa657double Te6edf3outbound_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Check if we have a known path for the destination in the path table
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3GROUP Tff7b72&Tff7b72& Te6edf3has_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// ── Multi-path hedging ───────────────────────────────────────
T8b949e// Walk all paths in score order (best first). Each path gets
T8b949e// the packet. If the path is stale (multi-hop transport only,
T8b949e// hops >= 2), fire a path_request to refresh it AND continue to
T8b949e// the next-best path so delivery isn't gated on a dead route.
T8b949e// The first fresh path stops the hedge.
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Path to destination is known, hedging...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3PathEntryTff7b72> Te6edf3paths Tff7b72= Te6edf3select_all_pathsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3pathsTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3hops Tff7b72= Te6edf3entryTb4b4b4.Te6edf3hopsTb4b4b4;
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3nh Tff7b72= Te6edf3entryTb4b4b4.Te6edf3next_hopTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4) Tff7b72continueTb4b4b4;
T8b949e// ── Build and transmit on this path ─────────────────
Tff7b72if Tb4b4b4(Te6edf3hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffForwarding packet to next closest interface...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff1Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3nhTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3hops Tff7b72=Tff7b72= T79c0ff1 Tff7b72&Tff7b72& Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet for directly connected interface to shared instance...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3nhTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet over directly connected interface...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// ── Staleness check (all hops) ────────────────────
T8b949e// Applies to ALL paths, not just multi-hop. A hops=1 path
T8b949e// through a migrated/disconnected client will go stale and
T8b949e// the hedge falls through to the next-best path (e.g. backbone).
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3is_stale Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3now Tff7b72- Te6edf3entryTb4b4b4.Te6edf3timestampTb4b4b4) Tff7b72> Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_STALE_THRESHOLDTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_staleTb4b4b4) Tb4b4b4{
T8b949e// Fire path_request on this path's interface to probe liveness
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4;
T8b949e// Shorten expiry so dead paths don't duplicate forever
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3e Tff7b72: Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3entryTb4b4b4.Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3shortened Tff7b72= Te6edf3now Tff7b72+ Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_STALE_THRESHOLDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3shortened Tff7b72< Te6edf3eTb4b4b4.Te6edf3expiresTb4b4b4) Tb4b4b4{
Te6edf3eTb4b4b4.Te6edf3expires Tff7b72= Te6edf3shortenedTb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Continue to next-best path (hedge)
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Fresh path — delivery covered, stop hedging
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// ── No path succeeded ─────────────────────────────────
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3sentTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (?) - NO-PATH hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff — all paths failed, droppedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// If we don't have a known path for the destination, we'll
T8b949e// broadcast the packet on all outgoing interfaces, or the
T8b949e// just the relevant interface if the packet has an attached
T8b949e// interface, or belongs to a link.
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Path to destination is unknownTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3stored_hash Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Checking interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3OUTTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3should_transmit Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3destination_linkTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3invalid_argumentTb4b4b4(Ta5d6ff"Ta5d6ffPacket is not associated with a LinkTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_linkTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3CLOSEDTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Pscket destination is link-closed, not transmittingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// CBA Bug? Destination has no member attached_interface
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3interface Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet has wrong attached interface, not transmittingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Firewall mode: announce broadcasts are always allowed.
T8b949e// No mode gating, no bandwidth caps — LAN announces go to
T8b949e// every interface including WAN, and whitelisted WAN
T8b949e// announces go to every LAN interface.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3interface Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// If the announce is pinned to a specific interface,
T8b949e// only transmit on that one.
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// No attached_interface means broadcast to all.
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3attached_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet has no attached interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ACCESS_POINTTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to AP modeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
T8b949e//Destination local_destination({Type::NONE});
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
T8b949e//if (local_destination) {
Tff7b72if Tb4b4b4(Te6edf3found_localTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//if (iter != _destinations.end()) {
T8b949e// local_destination = (*iter).second;
T8b949e//}
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAllowing announce broadcast on roaming-mode interface from instance-local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3from_interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//if from_interface == None or not hasattr(from_interface, "mode"):
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interface Tff7b72|Tff7b72| Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface doesn't existTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface has no mode configuredTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to roaming-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to boundary-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_BOUNDARYTb4b4b4) Tb4b4b4{
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == packet.destination_hash), None)
T8b949e// next and filter pattern?
T8b949e// next(iterable, default)
T8b949e// list comprehension: [x for x in xyz if x in a]
T8b949e// CBA TODO confirm that above pattern just selects the first matching destination
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e//Destination local_destination({Type::Destination::NONE});
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
T8b949e//if (local_destination) {
Tff7b72if Tb4b4b4(Te6edf3found_localTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAllowing announce broadcast on boundary-mode interface from instance-local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3from_interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interface Tff7b72|Tff7b72| Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface doesn't existTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_NONETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff since next hop interface has no mode configuredTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3from_interfaceTb4b4b4.Te6edf3modeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3InterfaceTff7b72:Tff7b72:Te6edf3MODE_ROAMINGTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking announce broadcast on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to roaming-mode next-hop interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Currently, annouces originating locally are always
T8b949e// allowed, and do not conform to bandwidth caps.
T8b949e// TODO: Rethink whether this is actually optimal.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// TODO
Tffa657bool Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queued_announces Tff7b72&Tff7b72& Te6edf3outbound_time Tff7b72> Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3wait_time Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3tx_time Tff7b72= Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff8Tb4b4b4) Tff7b72/ Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wait_time Tff7b72= Tb4b4b4(Te6edf3tx_time Tff7b72/ Te6edf3interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3outbound_time Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3outbound_time Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3should_transmit Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72< Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MAX_QUEUED_ANNOUNCESTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3should_queue Tff7b72= Tffa657trueTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3_destination Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint64_t Te6edf3emission_timestamp Tff7b72= Te6edf3announce_emittedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3should_queue Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3emission_timestamp Tff7b72> Te6edf3entryTb4b4b4.Te6edf3_emittedTb4b4b4) Tb4b4b4{
Te6edf3entryTb4b4b4.Te6edf3_time Tff7b72= Te6edf3outbound_timeTb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_hops Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_emitted Tff7b72= Te6edf3emission_timestampTb4b4b4;
Te6edf3entryTb4b4b4.Te6edf3_raw Tff7b72= Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3should_queueTb4b4b4) Tb4b4b4{
Te6edf3RNSTff7b72:Tff7b72:Te6edf3AnnounceEntry Te6edf3entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_timeTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3announce_emittedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4.Te6edf3add_announceTb4b4b4(Te6edf3entryTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
T8b949e// CBA ACCUMULATES
Te6edf3interfaceTb4b4b4.Te6edf3add_announceTb4b4b4(Te6edf3entryTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queued_announcesTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3wait_time Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657doubleTb4b4b4)T79c0ff0Tb4b4b4)Tb4b4b4;
T8b949e// CBA TODO THREAD?
Tff7b72if Tb4b4b4(Te6edf3wait_time Tff7b72< T79c0ff1000Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Te6edf3wait_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3wait_timeTff7b72/T79c0ff1000Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tffa657double Te6edf3wait_time Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657doubleTb4b4b4)T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3wait_time Tff7b72< T79c0ff1000Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Te6edf3wait_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdded announce to queue (height Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for processing in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3roundTb4b4b4(Te6edf3wait_timeTff7b72/T79c0ff1000Tb4b4b4,T79c0ff1Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif T8b949e// FIREWALL_MODE — announce gating
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3should_transmitTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet transmission allowedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: TX-OUT announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3stored_hashTb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_packet_hashlistTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3stored_hash Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// TODO: Re-evaluate potential for blocking
T8b949e// def send_packet():
T8b949e// Transport.transmit(interface, packet.raw)
T8b949e// thread = threading.Thread(target=send_packet)
T8b949e// thread.daemon = True
T8b949e// thread.start()
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3sent Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Packet transmission refusedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: TX-REFUSED announce dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff refused on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3sentTb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3sentTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3sent_atTb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Don't generate receipt if it has been explicitly disabled
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3create_receiptTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72&
T8b949e// Only generate receipts for DATA packets
Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATA Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for PLAIN destinations
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for link-related packets
Tff7b72!Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tff7b72&Tff7b72&
T8b949e// Don't generate receipts for resource packets
Tff7b72!Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_RCLTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3PacketReceipt Te6edf3receiptTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3receiptTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
Tff7b72return Te6edf3sentTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3packet_filterTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO: Think long and hard about this.
T8b949e// Is it even strictly necessary with the current
T8b949e// transport rules?
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3KEEPALIVETb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_REQTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_PRFTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCETb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CHANNELTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped PLAIN packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hopsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid PLAIN announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3GROUPTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped GROUP packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff with Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hopsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid GROUP announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_packet_hashlistTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_packet_hashlistTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::packet_filter: packet not previously seenTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::packet_filter: packet previously seen but is SINGLE ANNOUNCETa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDropped invalid announce packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffFILTERED duplicate packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: FILTERED dup dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3inboundTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3raw_inTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface T8b949e/*= {Type::NONE}*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: received %d bytesTa5d6ff"Tb4b4b4, Te6edf3raw_inTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3_packets_receivedTb4b4b4;
T8b949e// Heap telemetry: snapshot at entry
Tffa657size_t Te6edf3_heap_at_entry Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// CBA
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_receive_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3_callbacksTb4b4b4.Te6edf3_receive_packetTb4b4b4(Te6edf3raw_inTb4b4b4, Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing receive packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Mutable copy of raw data for IFAC processing
Te6edf3Bytes Te6edf3raw Tff7b72= Te6edf3raw_inTb4b4b4;
T8b949e// If interface access codes are enabled,
T8b949e// we must authenticate each packet.
Tff7b72if Tb4b4b4(Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff2Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72&Tff7b72& Te6edf3interfaceTb4b4b4.Te6edf3ifac_identityTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Check that IFAC flag is set
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x80Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0x80Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(T79c0ff2 Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Extract IFAC
Te6edf3Bytes Te6edf3ifac Tff7b72= Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Generate mask
Te6edf3Bytes Te6edf3mask Tff7b72= Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3hkdfTb4b4b4(
Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3ifacTb4b4b4,
Te6edf3interfaceTb4b4b4.Te6edf3ifac_keyTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// Unmask payload
Te6edf3Bytes Te6edf3unmasked_rawTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72<Tff7b72= T79c0ff1 Tff7b72|Tff7b72| Te6edf3i Tff7b72> Tb4b4b4(Tffa657size_tTb4b4b4)Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Unmask header bytes and payload
Te6edf3unmasked_rawTb4b4b4.Te6edf3appendTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3rawTb4b4b4[Te6edf3iTb4b4b4] Tff7b72^ Te6edf3maskTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Don't unmask IFAC itself
Te6edf3unmasked_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3raw Tff7b72= Te6edf3unmasked_rawTb4b4b4;
T8b949e// Unset IFAC flag
Tffa657uint8_t Te6edf3new_header0 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x7FTb4b4b4;
Tffa657uint8_t Te6edf3new_header1 Tff7b72= Te6edf3rawTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4;
T8b949e// Re-assemble packet without IFAC bytes
Te6edf3Bytes Te6edf3new_rawTb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header0Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3new_header1Tb4b4b4)Tb4b4b4;
Te6edf3new_rawTb4b4b4.Te6edf3appendTb4b4b4(Te6edf3rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2 Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Calculate expected IFAC
Te6edf3Bytes Te6edf3expected_signature Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3ifac_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3signTb4b4b4(Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3expected_ifac Tff7b72= Te6edf3expected_signatureTb4b4b4.Te6edf3rightTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3ifac_sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Check it
Tff7b72if Tb4b4b4(Te6edf3ifac Tff7b72=Tff7b72= Te6edf3expected_ifacTb4b4b4) Tb4b4b4{
Te6edf3raw Tff7b72= Te6edf3new_rawTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC authentication failed, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: packet too short for IFAC, droppingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If the IFAC flag is not set, but should be, drop the packet
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC required but flag not set, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If the interface does not have IFAC enabled,
T8b949e// check the received packet IFAC flag.
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3rawTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72& T79c0ff0x80Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0x80Tb4b4b4) Tb4b4b4{
T8b949e// If the flag is set, drop the packet
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: IFAC flag set but interface has no IFAC, dropping packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72while Tb4b4b4(Te6edf3_jobs_runningTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: sleeping...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(T79c0ff0.0005Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_identityTb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: No identity!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3_jobs_locked Tff7b72= Tffa657trueTb4b4b4;
Te6edf3Packet Te6edf3packetTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3DestinationTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4)Tb4b4b4, Te6edf3rawTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet unpack failed!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72ifndef NDEBUG
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: packet: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3debugStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: destination=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e// Helper: determine destination zone from path table / local dests
Tff7b72auto Te6edf3dest_zone Tff7b72= Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3hashTb4b4b4) Tff7b72-Tff7b72> Tff7b72const Tffa657charTff7b72* Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3hashTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4;
T8b949e// Check local registered destinations
Tff7b72#Tff7b72if defined(DESTINATIONS_MAP)
Tff7b72if Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3hashTb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffLANTa5d6ff"Tb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3d Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{ Tff7b72if Tb4b4b4(Te6edf3dTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3hashTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffLANTa5d6ff"Tb4b4b4; Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Check control hashes
Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3hashTb4b4b4) Tff7b72!Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffCTLTa5d6ff"Tb4b4b4;
T8b949e// Check path table
Tff7b72if Tb4b4b4(Te6edf3has_pathTb4b4b4(Te6edf3hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iface Tff7b72&Tff7b72& Te6edf3ifaceTb4b4b4.Te6edf3is_backboneTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffWANTa5d6ff"Tb4b4b4;
Tff7b72return Ta5d6ff"Ta5d6ffLANTa5d6ff"Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4;
Tb4b4b4}Tb4b4b4;
T8b949e// TODO
T8b949e//if (packet_filter(packet)) {
T8b949e// CBA
Tffa657bool Te6edf3accept Tff7b72= Tffa657trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_callbacksTb4b4b4.Te6edf3_filter_packetTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Te6edf3accept Tff7b72= Te6edf3_callbacksTb4b4b4.Te6edf3_filter_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffError while executing filter packet callback. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3acceptTb4b4b4) Tb4b4b4{
Te6edf3accept Tff7b72= Te6edf3packet_filterTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3acceptTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet accepted by filterTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE: Comprehensive firewall for backbone traffic.
T8b949e//
T8b949e// Three rules:
T8b949e// 1. Addresses that touch local interfaces (RNode/LoRa, LocalTCP)
T8b949e// get whitelisted on the backbone interface.
T8b949e// 2. Every packet referencing a whitelisted address — ALL identifiers
T8b949e// in that packet also get whitelisted (link hashes, announces,
T8b949e// requests, proofs, truncated hashes, transport IDs, EVERYTHING).
T8b949e// 3. Everything else gets blocked on the backbone interface.
T8b949e//
T8b949e// 4. TRANSITIVE WHITELIST: For every packet, extract ALL
T8b949e// identifiable addresses. If ANY address is already in a
T8b949e// whitelist, add ALL to the secondary whitelist. This covers
T8b949e// link IDs, ratchet IDs, transport IDs, path request targets,
T8b949e// and announce ratchets — in both directions.
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tb4b4b4{
Tffa657bool Te6edf3is_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// ── Extract all addresses from this packet ──────────
T8b949e// Two tiers:
T8b949e// TIER 1 (seed + check): user-facing destinations —
T8b949e// dest_hash, link_id, path_req_target, announce_ratchet.
T8b949e// These get added to WL#2 on pass.
T8b949e// TIER 2 (check only): relay infrastructure —
T8b949e// truncated_hash, transport_id. These can PERMIT a
T8b949e// packet through but are NEVER added to WL#2, because
T8b949e// they represent relay nodes, not user traffic.
Tff7b72auto Te6edf3wl_add Tff7b72= Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3addrTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3tagTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3addrTb4b4b4) Tff7b72returnTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3addrTb4b4b4) Tff7b72!Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72returnTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3wl2_pushTb4b4b4(Te6edf3addrTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffWL#2 ADD - Ta5d6ff" Tff7b72+ Te6edf3addrTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (from Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3tagTb4b4b4,Ta5d6ff"Ta5d6ffbackboneTa5d6ff"Tb4b4b4)Tff7b72=Tff7b72=T79c0ff0Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Tff7b72auto Te6edf3wl_known Tff7b72= Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3addrTb4b4b4) Tff7b72-Tff7b72> Tffa657bool Tb4b4b4{
Tff7b72return Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3addrTb4b4b4) Tff7b72!Tff7b72= Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)
Tff7b72|Tff7b72| Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3addrTb4b4b4) Tff7b72!Tff7b72= Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4;
T8b949e// Tier 1: user-facing addresses (seeded + checked)
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3addrsTb4b4b4;
Te6edf3addrsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3addrsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Path request: target destination in first 16 bytes of data
Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3addrsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Announce: extract ratchet ID (offset 84, 32 bytes, context_flag=FLAG_SET)
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3FLAG_SET
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff116Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3ratchet_pubkey Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff84Tb4b4b4, T79c0ff32Tb4b4b4)Tb4b4b4;
Te6edf3addrsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3ratchet_pubkeyTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// ── Watched-destination alias tracking ────────────
T8b949e// Populate ratchet and link aliases so WLOG resolves them.
Tff7b72#Tff7b72ifdef WATCH_LOG
Tb4b4b4{
Tff7b72const Tffa657charTff7b72* Te6edf3wn Tff7b72= Te6edf3watch_resolveTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3wnTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3context_flagTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3FLAG_SET
Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff116Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3rh Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3truncated_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff84Tb4b4b4, T79c0ff32Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3watch_add_aliasTb4b4b4(Te6edf3rhTb4b4b4, Te6edf3wnTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3lid Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3watch_add_aliasTb4b4b4(Te6edf3lidTb4b4b4, Te6edf3wnTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Tier 2: relay infrastructure (checked, NEVER seeded)
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3relay_addrsTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3header_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2 Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3relay_addrsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Note: getTruncatedHash() is NOT included — it's a
T8b949e// per-packet content hash, not a node identity. It can
T8b949e// never match a whitelist entry and seeding it wastes a
T8b949e// WL#2 slot with garbage.
T8b949e// ── Transitive match: any Tier 1 or Tier 2 address known? ──
Tffa657bool Te6edf3any_known Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3a Tff7b72: Te6edf3addrsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3wl_knownTb4b4b4(Te6edf3aTb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3any_known Tff7b72= Tffa657trueTb4b4b4; Tff7b72breakTb4b4b4; Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3any_knownTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3a Tff7b72: Te6edf3relay_addrsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3wl_knownTb4b4b4(Te6edf3aTb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3any_known Tff7b72= Tffa657trueTb4b4b4; Tff7b72breakTb4b4b4; Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3is_backboneTb4b4b4) Tb4b4b4{
T8b949e// === BACKBONE PACKET ===
T8b949e// Proofs are responses to traffic we already forwarded.
T8b949e// They carry no source/destination identity — just a
T8b949e// packet body hash. Exempt from whitelist; the reverse
T8b949e// table handles routing, and forged proofs fail signature
T8b949e// validation downstream.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - WL-PASS PROOF exempt hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Fall through to reverse-table routing below
Tb4b4b4}
T8b949e// Only allowed if at least one address in the packet is
T8b949e// already whitelisted (WL#1 or WL#2). No other gates.
Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3any_knownTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - WL-BLOCK hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
T8b949e// Transitive: add all addresses to WL#2
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3a Tff7b72: Te6edf3addrsTb4b4b4) Tb4b4b4{ Te6edf3wl_addTb4b4b4(Te6edf3aTb4b4b4, Ta5d6ff"Ta5d6ffbackboneTa5d6ff"Tb4b4b4)Tb4b4b4; Tb4b4b4}
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - WL-PASS hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// === LOCAL DEVICE PACKET ===
T8b949e// Always whitelist ALL addresses from local packets.
T8b949e// Local devices are trusted; their traffic seeds the
T8b949e// secondary whitelist for return traffic from WAN.
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3a Tff7b72: Te6edf3addrsTb4b4b4) Tb4b4b4{ Te6edf3wl_addTb4b4b4(Te6edf3aTb4b4b4, Ta5d6ff"Ta5d6fflocalTa5d6ff"Tb4b4b4)Tb4b4b4; Tb4b4b4}
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - WL-PASS hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Heap telemetry: snapshot after firewall filter (MUTED)
T8b949e// {
T8b949e// size_t _heap_after_boundary = OS::heap_available();
T8b949e// int _boundary_delta = (int)_heap_after_boundary - (int)_heap_at_entry;
T8b949e// if (_boundary_delta < -64) {
T8b949e// VERBOSEF("[HEAP-TEL] firewall: %d bytes (bma=%u phl=%u)", _boundary_delta, _firewall_mentioned_addresses.size(), _packet_hashlist.size());
T8b949e// }
T8b949e// }
T8b949e// By default, remember packet hashes to avoid routing
T8b949e// loops in the network, using the packet filter.
Tffa657bool Te6edf3remember_packet_hash Tff7b72= Tffa657trueTb4b4b4;
T8b949e// If this packet belongs to a link in our link table,
T8b949e// we'll have to defer adding it to the filter list.
T8b949e// In some cases, we might see a packet over a shared-
T8b949e// medium interface, belonging to a link that transports
T8b949e// or terminates with this instance, but before it would
T8b949e// normally reach us. If the packet is appended to the
T8b949e// filter list at this point, link transport will break.
Tff7b72if Tb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3remember_packet_hash Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// If this is a link request proof, don't add it until
T8b949e// we are sure it's not actually somewhere else in the
T8b949e// routing chain.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOF Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3remember_packet_hash Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3remember_packet_hashTb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_packet_hashlistTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Log ALL non-announce packets arriving from local (non-backbone) interfaces
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LAN-IN hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Resource packet trace: log any resource-context packet entering inbound
Tff7b72if Tb4b4b4(Te6edf3is_resource_ctxTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3ctx_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff IN hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff dst=Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e// Firewall mode: no local-client distinction. All devices are
T8b949e// either LAN (non-backbone) or WAN (backbone).
Tff7b72const Tffa657bool Te6edf3from_local_client Tff7b72= Tffa657falseTb4b4b4;
Tff7b72const Tffa657bool Te6edf3for_local_client Tff7b72= Tffa657falseTb4b4b4;
Tff7b72const Tffa657bool Te6edf3for_local_client_link Tff7b72= Tffa657falseTb4b4b4;
Tff7b72const Tffa657bool Te6edf3proof_for_local_client Tff7b72= Tffa657falseTb4b4b4;
T8b949e// Transport is always enabled in firewall mode
Tff7b72const Tffa657bool Te6edf3transport_active Tff7b72= Tffa657trueTb4b4b4;
T8b949e// If packet is not destined for a local transport-specific destination
Tff7b72if Tb4b4b4(Te6edf3_control_hashesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_control_hashesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// PLAIN BROADCAST: delivered to all interfaces
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAIN Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3transport_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Broadcasting packet on Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3interfaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e////////////////////////////////
T8b949e// TRANSPORT HANDLING
T8b949e////////////////////////////////
T8b949e// General transport handling (always active in firewall mode)
Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Performing general transport handlingTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// If this is a cache request, and we can fullfill
T8b949e// it, do so and stop processing. Otherwise resume
T8b949e// normal processing.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3cache_request_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Cached packetTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// If the packet is in transport, check whether we
T8b949e// are the designated next hop, and process it
T8b949e// accordingly if we are.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is in transport...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: We are designated next-hopTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3has_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Found next-hop path to destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffGot packet in transport, but selected path expired. Dropping packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3next_hop Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3next_hopTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3hopsTb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Just increase hop count and transmit
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += next_hop
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hopTb4b4b4;
T8b949e//new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72+T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72=Tff7b72= T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Strip transport headers and transmit
T8b949e//new_flags = (RNS.Packet.HEADER_1) << 6 | (Transport.BROADCAST) << 4 | (packet.flags & 0b00001111)
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6 Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4 Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = struct.pack("!B", new_flags)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72+T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// Just increase hop count and transmit
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// In firewall mode, never route a packet from backbone back to backbone.
T8b949e// The upstream server sent us this packet because we are the next hop,
T8b949e// so the destination must be on our local side.
Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72&Tff7b72& Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Path table incorrectly points to backbone. Skip forwarding.
Tb4b4b4}
Tff7b72else
Tff7b72#Tff7b72endif
Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is next-hop LINKREQUESTTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72+ Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hopsTb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
T8b949e// When forwarding a LINKREQUEST through this transport node,
T8b949e// clamp the link MTU signalling to min(prev-hop, next-hop)
T8b949e// interface HW_MTU. Without this, endpoints negotiate a
T8b949e// segment size that exceeds this node's buffer capacity,
T8b949e// causing silent truncation and resource transfer stalls.
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: No next-hop HW MTU, stripping link MTU signallingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: Outbound interface doesn't support MTU config, stripping link MTU signallingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: path=%u ph=%u nh=%u -> clamped=%uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3next_hopTb4b4b4,
Te6edf3outbound_interfaceTb4b4b4,
Te6edf3remaining_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Tffa657falseTb4b4b4,
Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is next-hop other typeTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3outbound_interfaceTb4b4b4,
Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3Bytes Te6edf3th Tff7b72= Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3thTb4b4b4)Tb4b4b4; Te6edf3_reverse_tableTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3thTb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3wl2_pushTb4b4b4(Te6edf3thTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::outbound: Sending packet to next hop...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) transport hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3remaining_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3transmitTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// Update timestamp on the selected path entry
Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3e Tff7b72: Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3eTb4b4b4.Te6edf3timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} T8b949e// firewall mode else
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// No path to destination. Link_ids are handled by the
T8b949e// link transport section below — only request a path
T8b949e// for locally-originated packets to unknown destinations.
Tb4b4b4{
Tffa657bool Te6edf3from_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3from_backbone Tff7b72&Tff7b72& Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - NO-PATH next-hop, requestingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72else
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffGot packet in transport, but no known path to final destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff. Dropping packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: We are not designated next-hop so not transportingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Either packet is announce or packet has no next-hop (possibly for a local destination)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// FIREWALL MODE: If this packet came from a local interface and we
T8b949e// have a path to the destination, wrap it with transport headers
T8b949e// and forward it through the backbone as the first transport hop.
T8b949e// Skip ANNOUNCE and PROOF packets — announces have their own handling,
T8b949e// and link proofs (LRPROOF) are handled by the LRPROOF transport code.
T8b949e// Also skip packets destined for locally-registered destinations
T8b949e// (e.g. path request handler) — those must be processed locally.
Tffa657bool Te6edf3is_local_destination Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_MAP)
Te6edf3is_local_destination Tff7b72= Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3dest Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3is_local_destination Tff7b72= Tffa657trueTb4b4b4; Tff7b72breakTb4b4b4; Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffFWD-CHECK - FROM: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3is_local_destination Tff7b72? Ta5d6ff"Ta5d6ffLOCALTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffFWDTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_local_destinationTb4b4b4) Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffSKIP-FWD - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff is local destTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Forward link proofs (delivery confirmations on established links)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_local_destination Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3link_it Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_it Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3LinkEntryTff7b72& Te6edf3le Tff7b72= Tb4b4b4(Tff7b72*Te6edf3link_itTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3Interface Te6edf3out_iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3leTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] - FROM: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3out_iface Tff7b72? Te6edf3out_ifaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3out_iface Tff7b72? Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3out_ifaceTb4b4b4)Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) LINK-PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3out_ifaceTb4b4b4) Te6edf3transmitTb4b4b4(Te6edf3out_ifaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_local_destination Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3is_from_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_from_backboneTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3Interface Te6edf3outbound_interface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3pkt_type_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff] - FROM: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3outbound_interface Tff7b72? Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Tb4b4b4(Te6edf3outbound_interface Tff7b72? Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4) Tff7b72: Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4) Tb4b4b4{
T8b949e// Path entry references an interface that no longer exists
T8b949e// (e.g. after reboot with persistent path table).
T8b949e// Request a fresh path instead of crashing.
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ff Saved path entry has stale interface hash — requesting fresh pathTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3next_hop Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3next_hopTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3hopsTb4b4b4;
T8b949e// Build outgoing packet based on remaining hops,
T8b949e// mirroring standard transport forwarding logic.
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Multi-hop: wrap with HEADER_2/TRANSPORT,
T8b949e// setting transport_id = next_hop (the next
T8b949e// transport node's identity hash from announce).
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hopTb4b4b4; T8b949e// insert transport_id
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Single hop (remaining_hops <= 1): destination is
T8b949e// directly reachable. Send as HEADER_1/BROADCAST
T8b949e// (no transport header), matching standard transport
T8b949e// behaviour for final-hop delivery.
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
T8b949e// Create link_table or reverse_table entry for return path
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72+ Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP
Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hopsTb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: local->backbone path=%u ph=%u nh=%u -> %uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4, Te6edf3next_hopTb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3remaining_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657falseTb4b4b4, Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
T8b949e// Each LINKREQUEST gets its own entry (unique link_id)
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interfaceTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3th Tff7b72= Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3thTb4b4b4)Tb4b4b4; Te6edf3_reverse_tableTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3thTb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// Whitelist the truncated hash so the return proof
T8b949e// from the backbone isn't blocked by the firewall.
Te6edf3wl2_pushTb4b4b4(Te6edf3thTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ff Forwarding local packet (Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3remaining_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops, Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytes) to Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
T8b949e// Update timestamp on selected path entry
Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3e Tff7b72: Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3eTb4b4b4.Te6edf3timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Only request path if the destination is not a link_id
T8b949e// (link data packets are handled by link transport below,
T8b949e// not by standard transport path lookup).
Tff7b72if Tb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - NO-PATH requestingTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// FIREWALL MODE REVERSE: Packet came from backbone,
T8b949e// check if destination is a local LoRa device and forward it.
Tff7b72if Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry2 Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entry2Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3next_hop2 Tff7b72= Te6edf3entry2Tff7b72-Tff7b72>Te6edf3next_hopTb4b4b4;
Tffa657uint8_t Te6edf3remaining_hops2 Tff7b72= Te6edf3entry2Tff7b72-Tff7b72>Te6edf3hopsTb4b4b4;
Te6edf3Interface Te6edf3outbound_interface2 Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entry2Tff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
T8b949e// Build properly routed packet based on remaining hops,
T8b949e// mirroring the standard transport forwarding logic.
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3remaining_hops2 Tff7b72> T79c0ff1Tb4b4b4) Tb4b4b4{
T8b949e// Multi-hop: wrap with HEADER_2/TRANSPORT
Tffa657uint8_t Te6edf3new_flags Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_2Tb4b4b4) Tff7b72<Tff7b72< T79c0ff6
Tff7b72| Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3TRANSPORTTb4b4b4) Tff7b72<Tff7b72< T79c0ff4
Tff7b72| Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3flagsTb4b4b4(Tb4b4b4) Tff7b72& T79c0ff0b00001111Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3new_flagsTb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3next_hop2Tb4b4b4; T8b949e// transport_id
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4; T8b949e// destination_hash + payload
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Direct or single-hop: send as HEADER_1
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Create link_table or reverse_table entry for return traffic
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3proof_timeout Tff7b72= Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72+ Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP
Tff7b72* Te6edf3stdTff7b72:Tff7b72:Te6edf3maxTb4b4b4(Tb4b4b4(Tffa657uint8_tTb4b4b4)T79c0ff1Tb4b4b4, Te6edf3remaining_hops2Tb4b4b4)Tb4b4b4;
T8b949e// === MTU Clamping (v1.0.12) ===
Tffa657uint16_t Te6edf3path_mtu Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3path_mtu Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3ph_mtu Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3nh_mtu Tff7b72= Te6edf3outbound_interface2Tb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_interface2Tb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tff7b72!Te6edf3outbound_interface2Tb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3nh_mtu Tff7b72< Te6edf3path_mtu Tff7b72|Tff7b72| Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3ph_mtu Tff7b72< Te6edf3path_mtuTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3clamped Tff7b72= Te6edf3stdTff7b72:Tff7b72:Te6edf3minTb4b4b4(Te6edf3nh_mtuTb4b4b4, Tb4b4b4(Te6edf3ph_mtu Tff7b72> T79c0ff0Tb4b4b4) Tff7b72? Te6edf3ph_mtu Tff7b72: Te6edf3nh_mtuTb4b4b4)Tb4b4b4;
Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_mode Te6edf3mode Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3clamped_mtu_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3clampedTb4b4b4, Te6edf3modeTb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72= Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4) Tff7b72+ Te6edf3clamped_mtu_bytesTb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffMTU CLAMP: backbone->local path=%u ph=%u nh=%u -> %uTa5d6ff"Tb4b4b4, Te6edf3path_mtuTb4b4b4, Te6edf3ph_mtuTb4b4b4, Te6edf3nh_mtuTb4b4b4, Te6edf3clampedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(
Te6edf3nowTb4b4b4, Te6edf3next_hop2Tb4b4b4, Te6edf3outbound_interface2Tb4b4b4, Te6edf3remaining_hops2Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657falseTb4b4b4, Te6edf3proof_timeout
Tb4b4b4)Tb4b4b4;
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ff Created link_table entry for backbone LINKREQUEST, link_id=Ta5d6ff" Tff7b72+ Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entryTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_interface2Tb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; Te6edf3_reverse_tableTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3getTruncatedHashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3reverse_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ff Forwarding backbone packet (Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3remaining_hops2Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops) to local device for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff via Ta5d6ff" Tff7b72+ Te6edf3outbound_interface2Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interface2Tb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
T8b949e// Update timestamp on selected path entry
Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3e Tff7b72: Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3entry2Tff7b72-Tff7b72>Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3eTb4b4b4.Te6edf3timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e// Link transport handling. Directs packets according
T8b949e// to entries in the link tables
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCE Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUEST Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking if packet is meant for link transport...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3link_iter Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_iter Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3LinkEntryTff7b72& Te6edf3link_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3link_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: pkt Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff type=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff ctx=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sz=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: entry hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff rem=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff val=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_validatedTb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// If receiving and outbound interface is
T8b949e// the same for this link, direction doesn't
T8b949e// matter, and we simply send the packet on.
Te6edf3Interface Te6edf3outbound_interfaceTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interface Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4) Tb4b4b4{
T8b949e// But check that taken hops matches one
T8b949e// of the expectede values.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hops Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Link inbound/outbound interfaes are same, transporting on same interfaceTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// If interfaces differ, we transmit on
T8b949e// the opposite interface of what the
T8b949e// packet was received on.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4) Tb4b4b4{
T8b949e// Reverse direction (from destination back toward initiator).
T8b949e// Match Python reference Transport.py line 1611: exact match.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4) Tb4b4b4{
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: HOP MISMATCH (from outbound) pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_resource_ctxTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3ctx_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff HOP-MISMATCH rev pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_remaining_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4) Tb4b4b4{
T8b949e// Also check that expected hop count matches
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3outbound_interface Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: HOP MISMATCH (from receiving) pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_resource_ctxTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3ctx_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff HOP-MISMATCH fwd pkt.hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: IFACE MISMATCH recv=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3outbound_interfaceTb4b4b4) Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: FWD to Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_resource_ctxTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3ctx_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff FWD to Ta5d6ff" Tff7b72+ Te6edf3outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_interfaceTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Add this packet to the filter hashlist now that
T8b949e// we have determined it's actually our turn to
T8b949e// process it (matching Python Transport line 1544).
Te6edf3_packet_hashlistTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw;
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
T8b949e//new_raw = packet.raw[0:1]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += struct.pack("!B", packet.hops)
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e//new_raw += packet.raw[2:]
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3link_entryTb4b4b4.Te6edf3_timestamp Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: DROPPED (no outbound interface resolved)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffLINK-XPORT: dest Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff NOT in link_table (size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3is_resource_ctxTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3ctx_nameTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff NO-LINKTABLE (size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e////////////////////////////////
T8b949e// LOCAL HANDLING
T8b949e////////////////////////////////
T8b949e// Announce handling. Handles logic related to incoming
T8b949e// announces, queueing rebroadcasts of these, and removal
T8b949e// of queued announce rebroadcasts once handed to the next node.
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3ANNOUNCETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is ANNOUNCETa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: ANNOUNCE-IN dest=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3received_fromTb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
T8b949e//Destination local_destination({Type::NONE});
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e//local_destination = destination;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination == None and RNS.Identity.validate_announce(packet):
T8b949e//if (!local_destination && Identity::validate_announce(packet)) {
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3found_local Tff7b72&Tff7b72& Te6edf3IdentityTff7b72:Tff7b72:Te6edf3validate_announceTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3IdentityTff7b72:Tff7b72:Te6edf3validate_announceTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for non-local destination, processing...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3received_from Tff7b72= Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Check if this is a next retransmission from
T8b949e// another node. If it is, we're removing the
T8b949e// announce in question from our pending table
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3_announce_tableTb4b4b4.Te6edf3countTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e//AnnounceEntry& announce_entry = _announce_table[packet.destination_hash()];
Te6edf3AnnounceEntryTff7b72& Te6edf3announce_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_announce_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= Te6edf3announce_entryTb4b4b4.Te6edf3_hopsTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffHeard a local rebroadcast of announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3announce_entryTb4b4b4.Te6edf3_local_rebroadcasts Tff7b72+Tff7b72= T79c0ff1Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_local_rebroadcasts Tff7b72>Tff7b72= Te6edf3LOCAL_REBROADCASTS_MAXTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffMax local rebroadcasts of announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff reached, dropping announce from our tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72- T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= Tb4b4b4(Te6edf3announce_entryTb4b4b4.Te6edf3_hops Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72&Tff7b72& Te6edf3announce_entryTb4b4b4.Te6edf3_retries Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72< Te6edf3announce_entryTb4b4b4.Te6edf3_timestampTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRebroadcasted announce for Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff has been passed on to another node, no further tries neededTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3received_from Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Check if this announce should be inserted into
T8b949e// announce and destination tables
Tffa657bool Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
T8b949e// First, check that the announce is not for a destination
T8b949e// local to this system, and that hops are less than the max
T8b949e// CBA TODO determine why packet destination hash is being searched in destinations again since we entered this logic becuase it did not exist above
T8b949e//if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3found_local Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72< Tb4b4b4(Te6edf3PATHFINDER_MTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4) Tff7b72< Tb4b4b4(Te6edf3PATHFINDER_MTff7b72+T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
T8b949e// ── Multi-Path Path Table Insertion ──────────────────────
T8b949e// 2 leaf outcomes instead of 11: replay check only.
T8b949e// All valid announces coexist; select_path() picks best at forwarding time.
Te6edf3Bytes Te6edf3random_blob Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8 Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3RANDOM_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e// Step 1: Anti-replay via global blob set
Tff7b72if Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3findTb4b4b4(Te6edf3_global_blobsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_global_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3random_blobTb4b4b4) Tff7b72!Tff7b72= Te6edf3_global_blobsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3should_add Tff7b72= Tffa657trueTb4b4b4;
Te6edf3_global_blobsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3random_blobTb4b4b4)Tb4b4b4;
T8b949e// Cap global_blobs at MAX_GLOBAL_BLOBS (FIFO eviction)
Tff7b72if Tb4b4b4(Te6edf3_global_blobsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3MAX_GLOBAL_BLOBSTb4b4b4) Tb4b4b4{
Te6edf3_global_blobsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3_global_blobsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// NOTE: The boundary-mode announce echo blocking that was here
T8b949e// has been removed. The standard random_blob check above
T8b949e// already prevents echoes (same blob = same announce bounced
T8b949e// through backbone). Removing the boundary-specific blocking
T8b949e// allows:
T8b949e// 1. Local TCP clients to receive backbone announces for
T8b949e// destinations that also have LoRa paths.
T8b949e// 2. The V3 destination table to contain the backbone path
T8b949e// when it is equal-or-better, enabling correct transport
T8b949e// routing for TCP client LINKREQUESTs.
T8b949e// LoRa-originated announces that arrive first will still be
T8b949e// preferred (equal hops = first-arrival wins via random_blob),
T8b949e// until the next re-announce cycle changes the path.
Tff7b72if Tb4b4b4(Te6edf3should_addTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3rate_blocked Tff7b72= Tffa657falseTb4b4b4;
T8b949e// TODO
Tffa657uint8_t Te6edf3retries Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint8_t Te6edf3announce_hops Tff7b72= Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3local_rebroadcasts Tff7b72= T79c0ff0Tb4b4b4;
Tffa657bool Te6edf3block_rebroadcasts Tff7b72= Tffa657falseTb4b4b4;
Te6edf3Interface Te6edf3attached_interface Tff7b72= Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tffa657double Te6edf3retransmit_timeout Tff7b72= Te6edf3now Tff7b72+ Tb4b4b4(Te6edf3CryptographyTff7b72:Tff7b72:Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3PATHFINDER_RWTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3expires Tff7b72= Te6edf3now Tff7b72+ Te6edf3PATHFINDER_ETb4b4b4;
T8b949e// ── Multi-Path Insertion ────────────────────────────
T8b949e// 1. Build PathEntry from announce fields
T8b949e// 2. Dedup within dest by packet_hash
T8b949e// 3. Push front (newest-first), truncate to MAX_PATHS_PER_DEST
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffCaching packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_packetTb4b4b4(Te6edf3packetTb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3cachedTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffAdding destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff to path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3PathEntry Te6edf3new_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3expiresTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tff7b72autoTff7b72& Te6edf3deque Tff7b72= Te6edf3_destination_tableTb4b4b4[Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4]Tb4b4b4;
Tffa657bool Te6edf3is_new_dest Tff7b72= Te6edf3dequeTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Remove any existing entry with the same packet_hash (same announce)
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tff7b72&Te6edf3new_entryTb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3new_entryTb4b4b4.Te6edf3packet_hashTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Prepend newest entry
Te6edf3dequeTb4b4b4.Te6edf3push_frontTb4b4b4(Te6edf3new_entryTb4b4b4)Tb4b4b4;
T8b949e// Cap at MAX_PATHS_PER_DEST
Tff7b72while Tb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3MAX_PATHS_PER_DESTTb4b4b4) Tb4b4b4{
Te6edf3dequeTb4b4b4.Te6edf3pop_backTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3is_new_destTb4b4b4) Tb4b4b4{
Tff7b72+Tff7b72+Te6edf3_destinations_addedTb4b4b4;
Te6edf3cull_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// ── Announce table insertion / retransmission ──────
T8b949e// In firewall mode, every announce (LAN or whitelisted WAN)
T8b949e// gets rebroadcast to all interfaces. No DISCOVERY_ADD
T8b949e// dependency — announces propagate naturally.
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72else
Tff7b72if Tb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3transport_enabledTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3rate_blockedTb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffBlocking rebroadcast of announce from Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to excessive announce rateTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// attached_interface stays NONE in firewall mode:
T8b949e// the announce will be broadcast to ALL interfaces,
T8b949e// not just the one it arrived on.
Te6edf3AnnounceEntry Te6edf3announce_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3retransmit_timeoutTb4b4b4,
Te6edf3retriesTb4b4b4,
Te6edf3received_fromTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3packetTb4b4b4,
Te6edf3local_rebroadcastsTb4b4b4,
Te6edf3block_rebroadcastsTb4b4b4,
Te6edf3attached_interface
Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDestination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff is now Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops away via Ta5d6ff" Tff7b72+ Te6edf3received_fromTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: STORED path Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3announce_hopsTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// FIREWALL MODE: Register destinations seen via non-backbone interfaces (Whitelist 1)
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Tb4b4b4{
Tffa657bool Te6edf3is_backbone Tff7b72= Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_backboneTb4b4b4) Tb4b4b4{
Te6edf3wl1_pushTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ffWL#1 ADD - Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (from LAN)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
T8b949e//TRACE("Transport::inbound: Destination " + packet.destination_hash().toHex() + " has data: " + packet.data().toHex());
T8b949e//TRACE("Transport::inbound: Destination " + packet.destination_hash().toHex() + " has text: " + packet.data().toString());
T8b949e// TODO
T8b949e/*
// If the receiving interface is a tunnel, we add the
// announce to the tunnels table
if (packet.receiving_interface().tunnel_id()) {
tunnel_entry = Transport.tunnels[packet.receiving_interface.tunnel_id];
paths = tunnel_entry[2];
paths[packet.destination_hash] = destination_table_entry;
expires = OS::time() + Transport::DESTINATION_TIMEOUT;
tunnel_entry[3] = expires;
DEBUG("Path to " + packet.destination_hash().toHex() + " associated with tunnel " + packet.receiving_interface().tunnel_id().toHex());
}
*/
T8b949e// Call externally registered callbacks from apps
T8b949e// wanting to know when an announce arrives
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PATH_RESPONSETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Not path response, sending to announce handler...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3handler Tff7b72: Te6edf3_announce_handlersTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking filter of announce handler...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
T8b949e// Check that the announced destination matches
T8b949e// the handlers aspect filter
Tffa657bool Te6edf3execute_callback Tff7b72= Tffa657falseTb4b4b4;
Te6edf3Identity Te6edf3announce_identityTb4b4b4(Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// If the handlers aspect filter is set to
T8b949e// None, we execute the callback in all cases
Te6edf3execute_callback Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3Bytes Te6edf3handler_expected_hash Tff7b72= Te6edf3DestinationTff7b72:Tff7b72:Te6edf3hash_from_name_and_identityTb4b4b4(Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_identityTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3handler_expected_hashTb4b4b4) Tb4b4b4{
Te6edf3execute_callback Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3execute_callbackTb4b4b4) Tb4b4b4{
T8b949e// CBA TODO Why does app data come from recall instead of from this announce packet?
Te6edf3handlerTff7b72-Tff7b72>Te6edf3received_announceTb4b4b4(
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3announce_identityTb4b4b4,
Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recall_app_dataTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while processing external announce callback.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for local destination, not processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is announce for local destination, not processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for link requests to local destinations
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LINKREQUESTTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LINKREQ-INTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3transport_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Checking if LINKREQUEST is for local destinationTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3found_local Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72autoTff7b72& Te6edf3destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Found local destination for LINKREQUESTTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Te6edf3found_local Tff7b72= Tffa657trueTb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72const_castTff7b72<Te6edf3DestinationTff7b72&Tff7b72>Tb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3destinationTb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72ifdef FIREWALL_MODE
T8b949e// Forward non-local link requests from non-backbone to backbone
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3found_local Tff7b72&Tff7b72& Tff7b72!Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Match Python: use the path table to find the correct
T8b949e// outbound interface, not broadcast to all backbones.
Te6edf3Interface Te6edf3outbound_ifaceTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3has_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3outbound_iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Fallback: use first connected backbone interface
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3outbound_ifaceTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3ifaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3ifaceTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3outbound_iface Tff7b72= Te6edf3ifaceTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Te6edf3outbound_ifaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3outbound_ifaceTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) LINKREQTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3outbound_iface Tff7b72&Tff7b72& Te6edf3outbound_iface Tff7b72!Tff7b72= Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3actual_hops Tff7b72= T79c0ff1Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3has_pathTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3actual_hops Tff7b72= Te6edf3hops_toTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3actual_hops Tff7b72< T79c0ff1Tb4b4b4) Te6edf3actual_hops Tff7b72= T79c0ff1Tb4b4b4;
Tb4b4b4}
Te6edf3LinkEntry Te6edf3link_entryTb4b4b4(Te6edf3nowTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3outbound_ifaceTb4b4b4, Te6edf3actual_hopsTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Tffa657falseTb4b4b4,
Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72+ Te6edf3now Tff7b72+ Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ESTABLISHMENT_TIMEOUT_PER_HOP Tff7b72* Te6edf3actual_hopsTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3link_id Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3link_id_from_lr_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Te6edf3_link_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Te6edf3_link_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3link_idTb4b4b4, Te6edf3link_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3wl2_pushTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3outbound_ifaceTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for data packets to local destinations
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATATa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
T8b949e// Data is destined for a link
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATA for a LINKTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is DATA for an active LINKTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3packetTb4b4b4.Te6edf3linkTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Data is basic (not destined for a link)
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Data is for a local destination
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LAN-DELIVERTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72autoTff7b72& Te6edf3destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet destination type Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff matched, processingTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3packetTb4b4b4.Te6edf3destinationTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72const_castTff7b72<Te6edf3DestinationTff7b72&Tff7b72>Tb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3destinationTb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_ALLTb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3proof_strategyTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PROVE_APPTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3callbacksTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3_proof_requestedTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3proveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Ta5d6ff"Ta5d6ffError while executing proof request callback. The contained exception was: Ta5d6ff"Tb4b4b4) Tff7b72+ Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet destination type Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff mismatch, ignoringTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Local destination Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff not found, not handling packet locallyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Handling for proofs and link-request proofs
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3packet_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3PROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3LRPROOFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is LINK PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// This is a link request proof, check if it
T8b949e// needs to be transported
Tff7b72if Tb4b4b4(Tb4b4b4(Tffa657trueTb4b4b4) Tff7b72&Tff7b72& Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_link_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: handling proof for link Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3LinkEntryTff7b72& Te6edf3link_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3_link_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) LRPROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: recv_iface=Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_out=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff entry_recv=Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3interface_match Tff7b72= Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3link_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interface_matchTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tffa657size_t Te6edf3expected_size Tff7b72= Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8 Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3expected_size_with_mtu Tff7b72= Te6edf3expected_size Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3LINK_MTU_SIZETb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size Tff7b72|Tff7b72| Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size_with_mtuTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3signalling_bytesTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3expected_size_with_mtuTb4b4b4) Tb4b4b4{
Te6edf3signalling_bytes Tff7b72= Te6edf3LinkTff7b72:Tff7b72:Te6edf3signalling_bytesTb4b4b4(Te6edf3LinkTff7b72:Tff7b72:Te6edf3mtu_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4, Te6edf3LinkTff7b72:Tff7b72:Te6edf3mode_from_lp_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3peer_pub_bytes Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3Identity Te6edf3peer_identity Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3recallTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3peer_identityTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-FAIL: no identity in cacheTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: peer identity recalled for Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3peer_sig_pub_bytes Tff7b72= Te6edf3peer_identityTb4b4b4.Te6edf3get_public_keyTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ECPUBSIZETff7b72/T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3Bytes Te6edf3signed_data Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3peer_pub_bytes Tff7b72+ Te6edf3peer_sig_pub_bytes Tff7b72+ Te6edf3signalling_bytesTb4b4b4;
Te6edf3Bytes Te6edf3signature Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3SIGLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3peer_identityTb4b4b4.Te6edf3validateTb4b4b4(Te6edf3signatureTb4b4b4, Te6edf3signed_dataTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: VALIDATED, forwarding to Ta5d6ff" Tff7b72+ Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw = packet.raw().left(1);
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: new_raw size=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3new_rawTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff hops=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff flags=0xTa5d6ff" Tff7b72+ Te6edf3new_rawTb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff dest=Ta5d6ff" Tff7b72+ Te6edf3new_rawTb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4, T79c0ff10Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff16Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3link_entryTb4b4b4.Te6edf3_validated Tff7b72= Tffa657trueTb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3link_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffLRPROOF-XPORT: transmit() returned OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-FAIL: invalid signatureTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} T8b949e// end peer_identity valid
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-FAIL: bad size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff expected Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3expected_sizeTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-FAIL: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffTO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-FAIL: iface mismatchTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Not in link_table or transport not enabled — check
T8b949e// if we can deliver it to a local pending link
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - LRPROOF-DROP not in link_table (lt=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff pl=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3_pending_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// CBA Must make a copy of _pending_links before traversing since it gets modified
T8b949e//for (auto link : _pending_links) {
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3pending_linksTb4b4b4(Te6edf3_pending_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3pending_linksTb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffChecking for link request handling by pending link %sTa5d6ff"Tb4b4b4, Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffRequesting pending link to validate proofTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3validate_proofTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3contextTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3RESOURCE_PRFTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is RESOURCE PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const_castTff7b72<Te6edf3LinkTff7b72&Tff7b72>Tb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::inbound: Packet is regular PROOFTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3LINKTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3setTff7b72<Te6edf3LinkTff7b72> Te6edf3active_linksTb4b4b4(Te6edf3_active_linksTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3link Tff7b72: Te6edf3active_linksTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3link_idTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3linkTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3Bytes Te6edf3proof_hashTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketReceiptTff7b72:Tff7b72:Te6edf3EXPL_LENGTHTb4b4b4) Tb4b4b4{
Te6edf3proof_hash Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Check if this proof needs to be transported
Tff7b72if Tb4b4b4(Tb4b4b4(Tffa657trueTb4b4b4) Tff7b72&Tff7b72& Te6edf3flatmap_findTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Te6edf3_reverse_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ReverseEntry Te6edf3reverse_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3flatmap_findTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] - FROM: Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - FWD: Ta5d6ff" Tff7b72+ Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3zone_tagTb4b4b4(Te6edf3is_backbone_interfaceTb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) REVTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3reverse_entryTb4b4b4.Te6edf3_outbound_interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffProof received on correct interface, transporting it via Ta5d6ff" Tff7b72+ Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// CBA RESERVE
T8b949e//Bytes new_raw = packet.raw().left(1);
Te6edf3Bytes Te6edf3new_rawTb4b4b4(T79c0ff512Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3leftTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3hopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3new_raw Tff7b72<Tff7b72< Te6edf3packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3transmitTb4b4b4(Te6edf3reverse_entryTb4b4b4.Te6edf3_receiving_interfaceTb4b4b4, Te6edf3new_rawTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffProof received on wrong interface, not transporting it.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[PROOF] - TO: Ta5d6ff" Tff7b72+ Te6edf3short_hashTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff (Ta5d6ff" Tff7b72+ Te6edf3dest_zoneTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff) - NO-REV cannot forwardTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3PacketReceiptTff7b72> Te6edf3cull_receiptsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3receipt_validated Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3proof_hashTb4b4b4) Tb4b4b4{
T8b949e// Only test validation if hash matches
Tff7b72if Tb4b4b4(Te6edf3receiptTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3proof_hashTb4b4b4) Tb4b4b4{
Te6edf3receipt_validated Tff7b72= Te6edf3receiptTb4b4b4.Te6edf3validate_proof_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// TODO: This looks like it should actually
T8b949e// be rewritten when implicit proofs are added.
T8b949e// In case of an implicit proof, we have
T8b949e// to check every single outstanding receipt
Te6edf3receipt_validated Tff7b72= Te6edf3receiptTb4b4b4.Te6edf3validate_proof_packetTb4b4b4(Te6edf3packetTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA TODO requires modifying of collection while iterating which is forbidden
Tff7b72if Tb4b4b4(Te6edf3receipt_validatedTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA since modifying of collection while iterating is forbidden
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3receipt Tff7b72: Te6edf3_receiptsTb4b4b4) Tb4b4b4{
Te6edf3cull_receiptsTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3receiptTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Heap telemetry: snapshot at exit (MUTED)
T8b949e// {
T8b949e// size_t _heap_at_exit = OS::heap_available();
T8b949e// int _inbound_delta = (int)_heap_at_exit - (int)_heap_at_entry;
T8b949e// static uint32_t _tel_pkt_count = 0;
T8b949e// ++_tel_pkt_count;
T8b949e// if (_inbound_delta < -64 || (_tel_pkt_count % 100 == 0)) {
T8b949e// VERBOSEF("[HEAP-TEL] inbound: %d bytes (heap=%u pin=%u bma=%u phl=%u lt=%u revr=%u)",
T8b949e// _inbound_delta, (uint32_t)_heap_at_exit, _packets_received,
T8b949e// _firewall_mentioned_addresses.size(), _packet_hashlist.size(),
T8b949e// _link_table.size(), _reverse_table.size());
T8b949e// }
T8b949e// }
Te6edf3_jobs_locked Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3synthesize_tunnelTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
T8b949e// TODO
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3tunnel_synthesize_handlerTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4, Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3handle_tunnelTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3tunnel_idTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
T8b949e// TODO
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_interfaceTb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Te6edf3_interfacesTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Te6edf3_interfacesTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Te6edf3_interfacesTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3interfaceTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// CBA TODO set or add transport as listener on interface to receive incoming packets?
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_interfaceTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(INTERFACES_SET)
T8b949e//for (auto iter = _interfaces.begin(); iter != _interfaces.end(); ++iter) {
T8b949e// if ((*iter).get() == interface) {
T8b949e// _interfaces.erase(iter);
T8b949e// TRACE("Transport::deregister_interface: Found and removed interface " + (*iter).get().toString());
T8b949e// break;
T8b949e// }
T8b949e//}
T8b949e//auto iter = _interfaces.find(interface);
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3interfaceTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tff7b72+Tff7b72+Te6edf3iterTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interfaceTb4b4b4) Tb4b4b4{
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3getTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_interface: Found and removed interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_interfacesTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_destinationTb4b4b4(Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
T8b949e//TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3destinationTb4b4b4.Te6edf3mtuTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3directionTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3INTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3registered_destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3registered_destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to register an already registered destination.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// CBA ACCUMULATES
Te6edf3_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to register an already registered destination.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// CBA ACCUMULATES
Te6edf3_destinationsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3destinationTb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3_owner Tff7b72&Tff7b72& Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3typeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3SINGLETb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport:register_destination: Announcing destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport:register_destination: Skipping registration (not direction IN) of destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
for (const Destination& destination : _destinations) {
for (auto& [hash, destination] : _destinations) {
TRACE("Transport::register_destination: Listed destination " + destination.toString());
}
*/
T8b949e//TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_destinationTb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72if Tb4b4b4(Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4) Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_destinationsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_destination: Found and removed destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_destinationsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_destination: Found and removed destination Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_linkTb4b4b4(Te6edf3LinkTff7b72& Te6edf3linkTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering link Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3initiatorTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_pending_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_active_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3activate_linkTb4b4b4(Te6edf3LinkTff7b72& Te6edf3linkTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Activating link Ta5d6ff" Tff7b72+ Te6edf3linkTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_pending_linksTb4b4b4.Te6edf3findTb4b4b4(Te6edf3linkTb4b4b4) Tff7b72!Tff7b72= Te6edf3_pending_linksTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4) Tff7b72!Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3stdTff7b72:Tff7b72:Te6edf3runtime_errorTb4b4b4(Ta5d6ff"Ta5d6ffInvalid link state for link activation: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3_pending_linksTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_active_linksTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4;
Te6edf3linkTb4b4b4.Te6edf3statusTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3LinkTff7b72:Tff7b72:Te6edf3ACTIVETb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffAttempted to activate a link that was not in the pending tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
Registers an announce handler.
:param handler: Must be an object with an *aspect_filter* attribute and a *received_announce(destination_hash, announced_identity, app_data)* callable. See the :ref:`Announce Example<example-announce>` for more info.
*/
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3register_announce_handlerTb4b4b4(Te6edf3HAnnounceHandler Te6edf3handlerTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Registering announce handler Ta5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_announce_handlersTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3handlerTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*
Deregisters an announce handler.
:param handler: The announce handler to be deregistered.
*/
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3deregister_announce_handlerTb4b4b4(Te6edf3HAnnounceHandler Te6edf3handlerTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport: Deregistering announce handler Ta5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_announce_handlersTb4b4b4.Te6edf3findTb4b4b4(Te6edf3handlerTb4b4b4) Tff7b72!Tff7b72= Te6edf3_announce_handlersTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_announce_handlersTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3handlerTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::deregister_announce_handler: Found and removed handlerTa5d6ff" Tff7b72+ Te6edf3handlerTff7b72-Tff7b72>Te6edf3aspect_filterTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Te6edf3Interface Te6edf3TransportTff7b72:Tff7b72:Te6edf3find_interface_from_hashTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3interface_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3interfaceTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3findTb4b4b4(Te6edf3interface_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_interfacesTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_interface_from_hash: Found interface Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3should_cache_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
T8b949e// TODO: Rework the caching system. It's currently
T8b949e// not very useful to even cache Resource proofs,
T8b949e// disabling it for now, until redesigned.
T8b949e// if packet.context == RNS.Packet.RESOURCE_PRF:
T8b949e// return True
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// When caching packets to storage, they are written
T8b949e// exactly as they arrived over their interface. This
T8b949e// means that they have not had their hop count
T8b949e// increased yet! Take note of this when reading from
T8b949e// the packet cache.
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4, Tffa657bool Te6edf3force_cache T8b949e/*= false*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffChecking to see if packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff should be cachedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72if Tb4b4b4(Te6edf3should_cache_packetTb4b4b4(Te6edf3packetTb4b4b4) Tff7b72|Tff7b72| Te6edf3force_cacheTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffSaving packet Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff to storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3serializeTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3packet_cache_pathTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError writing packet to cache. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Te6edf3Packet Te6edf3TransportTff7b72:Tff7b72:Te6edf3get_cached_packetTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffLoading packet Ta5d6ff" Tff7b72+ Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from cache storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72try Tb4b4b4{
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3packetTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3deserializeTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3packet_cache_pathTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3packetTb4b4b4.Te6edf3unpackTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3packetTb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while getting cached packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3clear_cached_packetTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffClearing packet Ta5d6ff" Tff7b72+ Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from cache storageTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72try Tb4b4b4{
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3start_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3success Tff7b72= Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3remove_fileTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3diff_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start_timeTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3diff_time Tff7b72< T79c0ff1.0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemove cached packet in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3diff_timeTff7b72*T79c0ff1000Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff msTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemove cached packet in Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3diff_timeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff sTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while clearing cached packet.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_request_packetTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PacketTff7b72& Te6edf3cached_packet Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cached_packetTb4b4b4) Tb4b4b4{
T8b949e// If the packet was retrieved from the local
T8b949e// cache, replay it to the Transport instance,
T8b949e// so that it can be directed towards it original
T8b949e// destination.
Te6edf3inboundTb4b4b4(Te6edf3cached_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cached_packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3cache_requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3packet_hashTb4b4b4, Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destinationTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PacketTff7b72& Te6edf3cached_packet Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cached_packetTb4b4b4) Tb4b4b4{
T8b949e// The packet was found in the local cache,
T8b949e// replay it to the Transport instance.
Te6edf3inboundTb4b4b4(Te6edf3cached_packetTb4b4b4.Te6edf3rawTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cached_packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// The packet is not in the local cache,
T8b949e// query the network.
Te6edf3Packet Te6edf3requestTb4b4b4(Te6edf3destinationTb4b4b4, Te6edf3packet_hashTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CACHE_REQUESTTb4b4b4)Tb4b4b4;
Te6edf3requestTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tff7b72const Te6edf3TransportTff7b72:Tff7b72:Te6edf3PathEntryTff7b72* Te6edf3TransportTff7b72:Tff7b72:Te6edf3select_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Tffa657nullptrTb4b4b4;
Tff7b72const Tff7b72autoTff7b72& Te6edf3deque Tff7b72= Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3best Tff7b72= Tffa657nullptrTb4b4b4;
Tffa657double Te6edf3best_score Tff7b72= T79c0ff-1.0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3dequeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3bitrate Tff7b72= Te6edf3iface Tff7b72? Te6edf3ifaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72: T79c0ff0Tb4b4b4;
Tffa657double Te6edf3s Tff7b72= Te6edf3entryTb4b4b4.Te6edf3scoreTb4b4b4(Te6edf3bitrateTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3s Tff7b72> Te6edf3best_scoreTb4b4b4) Tb4b4b4{
Te6edf3best_score Tff7b72= Te6edf3sTb4b4b4;
Te6edf3best Tff7b72= Tff7b72&Te6edf3entryTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3bestTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3TransportTff7b72:Tff7b72:Te6edf3PathEntryTff7b72> Te6edf3TransportTff7b72:Tff7b72:Te6edf3select_all_pathsTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3PathEntryTff7b72> Te6edf3resultTb4b4b4;
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3resultTb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;
Te6edf3resultTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3entryTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Sort by score descending (best first)
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3resultTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3resultTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tff7b72&Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3aTb4b4b4, Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3bTb4b4b4) Tb4b4b4{
Te6edf3Interface Te6edf3iface_a Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3aTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Te6edf3Interface Te6edf3iface_b Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3bTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3br_a Tff7b72= Te6edf3iface_a Tff7b72? Te6edf3iface_aTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72: T79c0ff0Tb4b4b4;
Tffa657uint32_t Te6edf3br_b Tff7b72= Te6edf3iface_b Tff7b72? Te6edf3iface_bTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72: T79c0ff0Tb4b4b4;
Tff7b72return Te6edf3aTb4b4b4.Te6edf3scoreTb4b4b4(Te6edf3br_aTb4b4b4) Tff7b72> Te6edf3bTb4b4b4.Te6edf3scoreTb4b4b4(Te6edf3br_bTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3resultTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// CBA also remove cached announce packet if exists
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: *True* if a path to the destination is known, otherwise *False*.
*/
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3has_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3select_pathTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72!Tff7b72= Tffa657nullptrTb4b4b4;
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The number of hops to the specified destination, or ``RNS.Transport.PATHFINDER_M`` if the number of hops is unknown.
*/
T8b949e/*static*/ Tffa657uint8_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3hops_toTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3entryTff7b72-Tff7b72>Te6edf3hopsTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Te6edf3PATHFINDER_MTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The destination hash as *bytes* for the next hop to the specified destination, or *None* if the next hop is unknown.
*/
T8b949e/*static*/ Te6edf3Bytes Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hopTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3entryTff7b72-Tff7b72>Te6edf3next_hopTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tb4b4b4{Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*
:param destination_hash: A destination hash as *bytes*.
:returns: The interface for the next hop to the specified destination, or *None* if the interface is unknown.
*/
T8b949e/*static*/ Te6edf3Interface Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interfaceTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint32_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interface_bitrateTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_interface_hw_mtuTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4.Te6edf3AUTOCONFIGURE_MTUTb4b4b4(Tb4b4b4) Tff7b72|Tff7b72| Te6edf3interfaceTb4b4b4.Te6edf3FIXED_MTUTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Te6edf3interfaceTb4b4b4.Te6edf3HW_MTUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72else Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_per_bit_latencyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3bitrate Tff7b72= Te6edf3next_hop_interface_bitrateTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bitrate Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(T79c0ff1.0Tff7b72/Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3bitrateTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3next_hop_per_byte_latencyTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3per_bit_latency Tff7b72= Te6edf3next_hop_per_bit_latencyTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3per_bit_latency Tff7b72> T79c0ff0.0Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3per_bit_latencyTff7b72*T79c0ff8.0Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3first_hop_timeoutTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3latency Tff7b72= Te6edf3next_hop_per_byte_latencyTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3latency Tff7b72> T79c0ff0.0Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTU Tff7b72* Te6edf3latency Tff7b72+ Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3DEFAULT_PER_HOP_TIMEOUTTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3DEFAULT_PER_HOP_TIMEOUTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657double Te6edf3TransportTff7b72:Tff7b72:Te6edf3extra_link_proof_timeoutTb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3interfaceTb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(Tb4b4b4(T79c0ff1.0Tff7b72/Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72*T79c0ff8.0Tb4b4b4)Tff7b72*Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3MTUTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tff7b72return T79c0ff0.0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3expire_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
T8b949e// Remove ALL entries for this destination (hard delete, not soft-expire)
Tff7b72return Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3mark_path_unresponsiveTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3blocked_interface T8b949e/*= {}*/Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72=Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Tffa657falseTb4b4b4;
Tff7b72autoTff7b72& Te6edf3deque Tff7b72= Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3blocked_interfaceTb4b4b4) Tb4b4b4{
T8b949e// No interface specified: remove all paths (backward compat)
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
T8b949e// Remove only entries matching the blocked interface
Tffa657size_t Te6edf3before Tff7b72= Te6edf3dequeTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tff7b72&Te6edf3blocked_interfaceTb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3eTb4b4b4.Te6edf3receiving_interface Tff7b72=Tff7b72= Te6edf3blocked_interfaceTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// If deque is now empty, remove the whole destination entry
Tff7b72if Tb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3dequeTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72< Te6edf3beforeTb4b4b4;
Tb4b4b4}
T8b949e/*
Requests a path to the destination from the network. If
another reachable peer on the network knows a path, it
will announce it.
:param destination_hash: A destination hash as *bytes*.
:param on_interface: If specified, the path request will only be sent on this interface. In normal use, Reticulum handles this automatically, and this parameter should not be used.
*/
T8b949e///*static*/ void Transport::request_path(const Bytes& destination_hash, const Interface& on_interface /*= {Type::NONE}*/, const Bytes& tag /*= {}*/, bool recursive /*= false*/) {
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3request_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3on_interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3tag T8b949e/*= {}*/Tb4b4b4, Tffa657bool Te6edf3recursive T8b949e/*= false*/Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3request_tagTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3tagTb4b4b4) Tb4b4b4{
Te6edf3request_tag Tff7b72= Te6edf3IdentityTff7b72:Tff7b72:Te6edf3get_random_hashTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3request_tag Tff7b72= Te6edf3tagTb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3path_request_dataTb4b4b4;
Tff7b72if Tb4b4b4(Tffa657trueTb4b4b4) Tb4b4b4{
Te6edf3path_request_data Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3_identityTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3request_tagTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3path_request_data Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3request_tagTb4b4b4;
Tb4b4b4}
Te6edf3Destination Te6edf3path_request_dstTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3OUTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3DestinationTff7b72:Tff7b72:Te6edf3PLAINTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffpath.requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3packetTb4b4b4(Te6edf3path_request_dstTb4b4b4, Te6edf3on_interfaceTb4b4b4, Te6edf3path_request_dataTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3DATATb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3CONTEXT_NONETb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3BROADCASTTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3HEADER_1Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3on_interface Tff7b72&Tff7b72& Te6edf3recursiveTb4b4b4) Tb4b4b4{
T8b949e// TODO
Tffa657bool Te6edf3queued_announces Tff7b72= Tb4b4b4(Te6edf3on_interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3queued_announcesTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking recursive path request on Ta5d6ff" Tff7b72+ Te6edf3on_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to queued announcesTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72< Te6edf3on_interfaceTb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffBlocking recursive path request on Ta5d6ff" Tff7b72+ Te6edf3on_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to active announce capTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Tffa657uint32_t Te6edf3wait_time Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4( Te6edf3on_interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3on_interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3tx_time Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3path_request_dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3HEADER_MINSIZETb4b4b4)Tff7b72*T79c0ff8Tb4b4b4) Tff7b72/ Te6edf3on_interfaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wait_time Tff7b72= Tb4b4b4(Te6edf3tx_time Tff7b72/ Te6edf3on_interfaceTb4b4b4.Te6edf3announce_capTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const_castTff7b72<Te6edf3InterfaceTff7b72&Tff7b72>Tb4b4b4(Te6edf3on_interfaceTb4b4b4)Tb4b4b4.Te6edf3announce_allowed_atTb4b4b4(Te6edf3now Tff7b72+ Te6edf3wait_timeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3packetTb4b4b4.Te6edf3sendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3flatmap_upsertTb4b4b4(Te6edf3_path_requestsTb4b4b4, Te6edf3destination_hashTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3request_pathTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3path_request_handlerTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3dataTb4b4b4, Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handlerTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= T79c0ff16Tb4b4b4) Tb4b4b4{ Te6edf3WLOGTb4b4b4(Te6edf3packetTb4b4b4, Ta5d6ff"Ta5d6ffPATH-REQ for Ta5d6ff" Tff7b72+ Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from Ta5d6ff" Tff7b72+ Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; Tb4b4b4}
Tff7b72try Tb4b4b4{
T8b949e// If there is at least bytes enough for a destination
T8b949e// hash in the packet, we assume those bytes are the
T8b949e// destination being requested.
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3destination_hash Tff7b72= Te6edf3dataTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: destination_hash: " + destination_hash.toHex());
T8b949e// If there is also enough bytes for a transport
T8b949e// instance ID and at least one tag byte, we
T8b949e// assume the next bytes to be the trasport ID
T8b949e// of the requesting transport instance.
Te6edf3Bytes Te6edf3requesting_transport_instanceTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tff7b72*T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3requesting_transport_instance Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: requesting_transport_instance: " + requesting_transport_instance.toHex());
Tb4b4b4}
Te6edf3Bytes Te6edf3tag_bytesTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3dataTb4b4b4.Te6edf3midTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3tag_bytesTb4b4b4) Tb4b4b4{
T8b949e//TRACE("Transport::path_request_handler: tag_bytes: " + tag_bytes.toHex());
Tff7b72if Tb4b4b4(Te6edf3tag_bytesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4) Tb4b4b4{
Te6edf3tag_bytes Tff7b72= Te6edf3tag_bytesTb4b4b4.Te6edf3leftTb4b4b4(Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3TRUNCATED_HASHLENGTHTff7b72/T79c0ff8Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3Bytes Te6edf3unique_tag Tff7b72= Te6edf3destination_hash Tff7b72+ Te6edf3tag_bytesTb4b4b4;
T8b949e//TRACE("Transport::path_request_handler: unique_tag: " + unique_tag.toHex());
Tff7b72if Tb4b4b4(Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3unique_tagTb4b4b4) Tff7b72=Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// CBA ACCUMULATES
Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3insertTb4b4b4(Te6edf3unique_tagTb4b4b4)Tb4b4b4;
Te6edf3path_requestTb4b4b4(
Te6edf3destination_hashTb4b4b4,
Tffa657falseTb4b4b4,
Te6edf3packetTb4b4b4.Te6edf3receiving_interfaceTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3requesting_transport_instanceTb4b4b4,
Te6edf3tag_bytes
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3NOTICETb4b4b4(Ta5d6ff"Ta5d6ff[PKT] PATH-REQ-DUP for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring tagless path request for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffError while handling path request. The contained exception was: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTb4b4b4(Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3path_requestTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4, Tffa657bool Te6edf3is_from_local_clientTb4b4b4, Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3attached_interfaceTb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3requestor_transport_id T8b949e/*= {}*/Tb4b4b4, Tff7b72const Te6edf3BytesTff7b72& Te6edf3tag T8b949e/*= {}*/Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_requestTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3should_search_for_unknown Tff7b72= Tffa657falseTb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3string Te6edf3interface_strTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attached_interfaceTb4b4b4) Tb4b4b4{
Te6edf3should_search_for_unknown Tff7b72= Tffa657trueTb4b4b4;
Te6edf3interface_str Tff7b72= Ta5d6ff"Ta5d6ff on Ta5d6ff" Tff7b72+ Te6edf3attached_interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffPath request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3destination_exists_on_local_client Tff7b72= Tffa657falseTb4b4b4;
Tff7b72if Tb4b4b4(Tffa657falseTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3has_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3next_hop_interfaceTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tffa657falseTb4b4b4) Tb4b4b4{
Te6edf3destination_exists_on_local_client Tff7b72= Tffa657trueTb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3destination_hashTb4b4b4, Te6edf3attached_interfaceTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry not found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72auto Te6edf3destination_iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
T8b949e//local_destination = next((d for d in Transport.destinations if d.hash == destination_hash), None)
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Te6edf3Destination Te6edf3local_destinationTb4b4b4(Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3local_destination Tff7b72= Te6edf3destinationTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e//if local_destination != None:
Tff7b72if Tb4b4b4(Te6edf3local_destinationTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72autoTff7b72& Te6edf3local_destination Tff7b72= Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3local_destinationTb4b4b4.Te6edf3announceTb4b4b4(Tb4b4b4{Te6edf3BytesTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4, Tffa657trueTb4b4b4, Te6edf3attached_interfaceTb4b4b4, Te6edf3tagTb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAnswering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, destination is local to this systemTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Tb4b4b4(Tffa657trueTb4b4b4) Tff7b72&Tff7b72& Te6edf3has_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: entry found for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3PathEntryTff7b72* Te6edf3entry Tff7b72= Te6edf3select_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffpath_request: selected path expired for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3PacketTff7b72& Te6edf3announce_packet Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3BytesTff7b72& Te6edf3next_hop Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3next_hopTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3announce_packetTb4b4b4) Tb4b4b4{
T8b949e// Cache file missing or corrupt — remove the stale entry and bail
Te6edf3WARNINGTb4b4b4(Ta5d6ff"Ta5d6ffpath_request: removing stale path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff due to missing announce packet cacheTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Remove the specific entry with the missing cache
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tff7b72&Te6edf3entryTb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3eTb4b4b4.Te6edf3packet_hash Tff7b72=Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3packet_hashTb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4,
Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iterTff7b72-Tff7b72>Te6edf3secondTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3receiving_interface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTff7b72-Tff7b72>Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3requestor_transport_id Tff7b72&Tff7b72& Te6edf3entryTff7b72-Tff7b72>Te6edf3next_hop Tff7b72=Tff7b72= Te6edf3requestor_transport_idTb4b4b4) Tb4b4b4{
T8b949e// TODO: Find a bandwidth efficient way to invalidate our
T8b949e// known path on this signal. The obvious way of signing
T8b949e// path requests with transport instance keys is quite
T8b949e// inefficient. There is probably a better way. Doing
T8b949e// path invalidation here would decrease the network
T8b949e// convergence time. Maybe just drop it?
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffNot answering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, since next hop is the requestorTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAnswering path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, path is knownTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffDIAG: PATH-RESP for Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4) Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3retries Tff7b72= Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATHFINDER_RTb4b4b4;
Tffa657uint8_t Te6edf3local_rebroadcasts Tff7b72= T79c0ff0Tb4b4b4;
Tffa657bool Te6edf3block_rebroadcasts Tff7b72= Tffa657trueTb4b4b4;
T8b949e// Use PathEntry.hops (correct hop count from announce, not stale wire bytes)
Tffa657uint8_t Te6edf3announce_hops Tff7b72= Te6edf3entryTff7b72-Tff7b72>Te6edf3hopsTb4b4b4;
Tffa657double Te6edf3retransmit_timeout Tff7b72= Te6edf3now Tff7b72+ Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_REQUEST_GRACETb4b4b4;
T8b949e// This handles an edge case where a peer sends a past
T8b949e// request for a destination just after an announce for
T8b949e// said destination has arrived, but before it has been
T8b949e// rebroadcast locally. In such a case the actual announce
T8b949e// is temporarily held, and then reinserted when the path
T8b949e// request has been served to the peer.
Tff7b72auto Te6edf3announce_iter Tff7b72= Te6edf3_announce_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3announce_iter Tff7b72!Tff7b72= Te6edf3_announce_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3AnnounceEntryTff7b72& Te6edf3held_entry Tff7b72= Tb4b4b4(Tff7b72*Te6edf3announce_iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_held_announcesTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3held_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
T8b949e// BUG FIX: Must erase old entry before insert(),
T8b949e// since std::map::insert() is a no-op when key exists.
T8b949e// Python dict assignment overwrites, but C++ insert does not.
Te6edf3_announce_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3announce_iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3AnnounceEntry Te6edf3announce_entryTb4b4b4(
Te6edf3nowTb4b4b4,
Te6edf3retransmit_timeoutTb4b4b4,
Te6edf3retriesTb4b4b4,
Te6edf3next_hopTb4b4b4,
Te6edf3announce_hopsTb4b4b4,
Te6edf3announce_packetTb4b4b4,
Te6edf3local_rebroadcastsTb4b4b4,
Te6edf3block_rebroadcastsTb4b4b4,
Te6edf3attached_interface
Tb4b4b4)Tb4b4b4;
T8b949e// CBA ACCUMULATES
Te6edf3_announce_tableTb4b4b4.Te6edf3insertTb4b4b4(Tb4b4b4{Te6edf3announce_packetTb4b4b4.Te6edf3destination_hashTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3announce_entryTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3should_search_for_unknownTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request_handler: searching for unknown path to Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3flatmap_findTb4b4b4(Te6edf3_discovery_path_requestsTb4b4b4, Te6edf3destination_hashTb4b4b4) Tff7b72!Tff7b72= Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffThere is already a waiting path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on behalf of path requestTa5d6ff" Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Forward path request on all interfaces.
T8b949e// Only skip same-interface forwarding for point-to-point
T8b949e// interfaces (backbone) — echoing back to the sender on a
T8b949e// point-to-point link is just noise. Broadcast interfaces
T8b949e// (LoRa) reach different nodes when retransmitted, and any
T8b949e// echo is already caught by _discovery_path_requests /
T8b949e// _discovery_pr_tags dedup.
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffAttempting to discover unknown path to destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff on behalf of path requestTa5d6ff" Tff7b72+ Te6edf3interface_strTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(FIREWALL_MODE)
T8b949e// Track this destination in Whitelist 2 so the path
T8b949e// response announce from the backbone will be allowed through
Te6edf3wl2_pushTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if defined(INTERFACES_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_LIST)
Tff7b72for Tb4b4b4(Te6edf3InterfaceTff7b72& Te6edf3interface Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72elif defined(INTERFACES_MAP)
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3interface Tff7b72=Tff7b72= Te6edf3attached_interface Tff7b72&Tff7b72& Te6edf3interfaceTb4b4b4.Te6edf3is_backboneTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request: not requesting path back to sender on backbone Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::path_request: requesting path on interface Ta5d6ff" Tff7b72+ Te6edf3interfaceTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3request_pathTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3interfaceTb4b4b4, Te6edf3tagTb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffIgnoring path request for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3interface_str Tff7b72+ Ta5d6ff"Ta5d6ff, no path knownTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint64_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3announce_emittedTb4b4b4(Tff7b72const Te6edf3PacketTff7b72& Te6edf3packetTb4b4b4) Tb4b4b4{
Te6edf3Bytes Te6edf3random_blob Tff7b72= Te6edf3packetTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3midTb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3KEYSIZETff7b72/T79c0ff8Tff7b72+Te6edf3RNSTff7b72:Tff7b72:Te6edf3TypeTff7b72:Tff7b72:Te6edf3IdentityTff7b72:Tff7b72:Te6edf3NAME_HASH_LENGTHTff7b72/T79c0ff8Tb4b4b4, T79c0ff10Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3random_blobTb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3OSTff7b72:Tff7b72:Te6edf3from_bytes_big_endianTb4b4b4(Te6edf3random_blobTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4) Tff7b72+ T79c0ff5Tb4b4b4, T79c0ff5Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3drop_announce_queuesTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// No-op in firewall mode: announce queues handled by jobs() loop
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_packet_hashlistTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e//#define CUSTOM 1
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3read_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::read_path_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3OSTff7b72:Tff7b72:Te6edf3file_existsTb4b4b4(Te6edf3destination_table_pathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72#Tff7b72if CUSTOM
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer capacity %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3capacityTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3read_fileTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: read: %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer addr: 0x%XTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: buffer size %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("SERIALIZED: destination_table");
T8b949e//TRACE(Persistence::_buffer.toString());
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifdef USE_MSGPACK
Te6edf3DeserializationError Te6edf3error Tff7b72= Te6edf3deserializeMsgPackTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3DeserializationError Te6edf3error Tff7b72= Te6edf3deserializeJsonTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: doc size: %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3errorTb4b4b4) Tb4b4b4{
T8b949e// Calculate crc for dirty-checking before write
Te6edf3_destination_table_crc Tff7b72= Te6edf3CrcTff7b72:Tff7b72:Te6edf3crc32Tb4b4b4(T79c0ff0Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_destination_table Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3asTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3dequeTff7b72<Te6edf3PathEntryTff7b72>Tff7b72>Tff7b72>Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else T8b949e// CUSTOM
T8b949e// Calculate crc for dirty-checking before write
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3deserializeTb4b4b4(Te6edf3_destination_tableTb4b4b4, Te6edf3destination_table_pathTb4b4b4, Te6edf3_destination_table_crcTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: successfully deserialized path table with %d entriesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3invalid_pathsTb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
T8b949e// Remove individual entries with missing packet cache or interface
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Te6edf3PathEntryTff7b72& Te6edf3entryTb4b4b4) Tb4b4b4{
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Te6edf3Packet Te6edf3pkt Tff7b72= Te6edf3get_cached_packetTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3packet_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3iface Tff7b72|Tff7b72| Tff7b72!Te6edf3pktTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4; T8b949e// remove — interface or cache missing
Tb4b4b4}
T8b949e// Drop paths through interfaces that have no connected
T8b949e// clients at boot. TCP client connections don't survive
T8b949e// reboots, so saved paths through LocalTcpInterface are
T8b949e// dead until the client reconnects and re-announces.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3ifaceTb4b4b4.Te6edf3isConnectedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4; T8b949e// remove — no clients connected
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3invalid_pathsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Reset timestamps to boot time minus staleness threshold.
T8b949e// Without NTP, saved timestamps are seconds-since-boot from
T8b949e// a previous session and are meaningless after reboot.
T8b949e// Starting stale causes the first packet to each destination
T8b949e// to hedge immediately, firing a path_request to revalidate.
Tffa657double Te6edf3stale_time Tff7b72= Te6edf3now Tff7b72- Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3TypeTff7b72:Tff7b72:Te6edf3TransportTff7b72:Tff7b72:Te6edf3PATH_STALE_THRESHOLD Tff7b72- T79c0ff1.0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3dequeTb4b4b4) Tb4b4b4{
Te6edf3entryTb4b4b4.Te6edf3timestamp Tff7b72= Te6edf3stale_timeTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3invalid_pathsTb4b4b4) Tb4b4b4{
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Enforce maxsize on loaded paths (trim lowest-score if over limit)
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: trimming loaded path table from %d to %d entriesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_path_table_maxsizeTb4b4b4)Tb4b4b4;
Te6edf3cull_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Memory diagnostic after path table load
Tffa657size_t Te6edf3total_entries Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Te6edf3total_entries Tff7b72+Tff7b72= Te6edf3dequeTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: path table: %d dests, %d total entriesTa5d6ff"Tb4b4b4,
Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3total_entriesTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: failed to deserializeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if CUSTOM
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::start: destination table read failedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else T8b949e// CUSTOM
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffLoaded %d valid path table entries from storageTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffCould not load destination table from storage, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657bool Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3TransportTff7b72:Tff7b72:Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Te6edf3success Tff7b72= Tffa657falseTb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
Tff7b72if Tb4b4b4(Te6edf3_saving_path_tableTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3wait_interval Tff7b72= T79c0ff0.2Tb4b4b4;
Tffa657double Te6edf3wait_timeout Tff7b72= T79c0ff5Tb4b4b4;
Tffa657double Te6edf3wait_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3_saving_path_tableTb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3sleepTb4b4b4(Te6edf3wait_intervalTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72> Tb4b4b4(Te6edf3wait_start Tff7b72+ Te6edf3wait_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ERRORTb4b4b4(Ta5d6ff"Ta5d6ffCould not save path table to storage, waiting for previous save operation timed out.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72try Tb4b4b4{
Te6edf3_saving_path_table Tff7b72= Tffa657trueTb4b4b4;
Tffa657double Te6edf3save_start Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaving %d path table entries to storage...Ta5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// Enforce maxpersist: create a trimmed copy for serialization
T8b949e// keeping only the destinations with the best-score paths
Te6edf3stdTff7b72:Tff7b72:Te6edf3mapTff7b72<Te6edf3BytesTb4b4b4, Te6edf3stdTff7b72:Tff7b72:Te6edf3dequeTff7b72<Te6edf3PathEntryTff7b72>Tff7b72> Te6edf3persist_tableTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3_path_table_maxpersistTb4b4b4) Tb4b4b4{
Te6edf3persist_table Tff7b72= Te6edf3_destination_tableTb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e// Sort destinations by best path score, keep top N
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72> Te6edf3scoredTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3dest_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3best_score Tff7b72= T79c0ff-1.0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3dequeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3s Tff7b72= Te6edf3entryTb4b4b4.Te6edf3scoreTb4b4b4(Te6edf3iface Tff7b72? Te6edf3ifaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3s Tff7b72> Te6edf3best_scoreTb4b4b4) Te6edf3best_score Tff7b72= Te6edf3sTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3best_score Tff7b72< T79c0ff0Tb4b4b4) Te6edf3best_score Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3scoredTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3dest_hashTb4b4b4, Te6edf3best_scoreTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3scoredTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3scoredTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72& Te6edf3aTb4b4b4, Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72& Te6edf3bTb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3aTb4b4b4.Te6edf3second Tff7b72> Te6edf3bTb4b4b4.Te6edf3secondTb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657size_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3_path_table_maxpersist Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3scoredTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3findTb4b4b4(Te6edf3scoredTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3firstTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destination_tableTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3persist_tableTb4b4b4.Te6edf3insertTb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTrimmed path table from %d to %d destinations for persistenceTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3persist_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if CUSTOM
Tb4b4b4{
Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3setTb4b4b4(Te6edf3persist_tableTb4b4b4)Tb4b4b4;
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: doc size %d bytesTa5d6ff"Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4.Te6edf3memoryUsageTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e//size_t size = 8192;
Tffa657size_t Te6edf3size Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3capacityTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: obtaining buffer size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3sizeTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657uint8_tTff7b72* Te6edf3buffer Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3writableTb4b4b4(Te6edf3sizeTb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer addr: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657longTb4b4b4)Te6edf3bufferTb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef USE_MSGPACK
Tffa657size_t Te6edf3length Tff7b72= Te6edf3serializeMsgPackTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3bufferTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tffa657size_t Te6edf3length Tff7b72= Te6edf3serializeJsonTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_documentTb4b4b4, Te6edf3bufferTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: serialized %d bytesTa5d6ff"Tb4b4b4, Te6edf3lengthTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3length Tff7b72< Te6edf3sizeTb4b4b4) Tb4b4b4{
Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3resizeTb4b4b4(Te6edf3lengthTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer addr: Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Tb4b4b4(Tffa657longTb4b4b4)Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: buffer size Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff bytesTa5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e//TRACE("SERIALIZED: destination_table");
T8b949e//TRACE(Persistence::_buffer.toString());
Tff7b72#Tff7b72endif
T8b949e// Check crc to see if data has changed before writing
Tffa657uint32_t Te6edf3crc Tff7b72= Te6edf3CrcTff7b72:Tff7b72:Te6edf3crc32Tb4b4b4(T79c0ff0Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3dataTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_table_crc Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3crc Tff7b72=Tff7b72= Te6edf3_destination_table_crcTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: no change detected, skipping writeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tff7b72if Tb4b4b4(Te6edf3RNSTff7b72:Tff7b72:Te6edf3UtilitiesTff7b72:Tff7b72:Te6edf3OSTff7b72:Tff7b72:Te6edf3write_fileTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4) Tff7b72=Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: wrote %d entries, %d bytesTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_destination_table_crc Tff7b72= Te6edf3crcTb4b4b4;
Te6edf3success Tff7b72= Tffa657trueTb4b4b4;
Tff7b72#Tff7b72ifndef NDEBUG
T8b949e// CBA DEBUG Dump path table
T8b949e//TRACE("FILE: destination_table");
T8b949e//if (OS::read_file("/destination_table", Persistence::_buffer) > 0) {
T8b949e// TRACE(Persistence::_buffer.toString());
T8b949e//}
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: write failedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: failed to serializeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else T8b949e// CUSTOM
Tffa657uint32_t Te6edf3crc Tff7b72= Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3crcTb4b4b4(Te6edf3persist_tableTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_destination_table_crc Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3crc Tff7b72=Tff7b72= Te6edf3_destination_table_crcTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: no change detected, skipping writeTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: change detected, writing...Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657char Te6edf3destination_table_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3destination_table_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/destination_tableTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_storagepathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3serializeTb4b4b4(Te6edf3persist_tableTb4b4b4, Te6edf3destination_table_pathTb4b4b4, Te6edf3_destination_table_crcTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::write_path_table: wrote %d entries, %d bytesTa5d6ff"Tb4b4b4, Te6edf3persist_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PersistenceTff7b72:Tff7b72:Te6edf3_bufferTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif T8b949e// CUSTOM
Tff7b72if Tb4b4b4(Te6edf3successTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3save_time Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3save_startTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3save_time Tff7b72< T79c0ff1.0Tb4b4b4) Tb4b4b4{
T8b949e//DEBUG("Saved " + std::to_string(_destination_table.size()) + " path table entries in " + std::to_string(OS::round(save_time * 1000, 1)) + " ms");
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaved %d path table entries in %d msTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Te6edf3save_timeTff7b72*T79c0ff1000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72else Tb4b4b4{
T8b949e//DEBUG("Saved " + std::to_string(_destination_table.size()) + " path table entries in " + std::to_string(OS::round(save_time, 1)) + " s");
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffSaved %d path table entries in %d sTa5d6ff"Tb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3save_timeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72catch Tb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3exceptionTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3ERRORFTb4b4b4(Ta5d6ff"Ta5d6ffCould not save path table to storage, the contained exception was: %sTa5d6ff"Tb4b4b4, Te6edf3eTb4b4b4.Te6edf3whatTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Te6edf3_saving_path_table Tff7b72= Tffa657falseTb4b4b4;
Tff7b72return Te6edf3successTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3read_tunnel_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffTransport::read_tunnel_tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3write_tunnel_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// TODO
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3persist_dataTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::persist_data()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3write_packet_hashlistTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3write_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3write_tunnel_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3clean_cachesTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(RNS_USE_FS) && defined(RNS_PERSIST_PATHS)
T8b949e// CBA Remove cached packets no longer in path list
Te6edf3stdTff7b72:Tff7b72:Te6edf3listTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3stringTff7b72> Te6edf3files Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3list_directoryTb4b4b4(Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3file Tff7b72: Te6edf3filesTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches: Checking for use of cached packet Ta5d6ff" Tff7b72+ Te6edf3fileTb4b4b4)Tb4b4b4;
Tffa657bool Te6edf3found Tff7b72= Tffa657falseTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3dequeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3compareTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3packet_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3found Tff7b72= Tffa657trueTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3foundTb4b4b4) Tff7b72breakTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3foundTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clean_caches: No matching path found, removing cached packet Ta5d6ff" Tff7b72+ Te6edf3fileTb4b4b4)Tb4b4b4;
Tffa657char Te6edf3packet_cache_pathTb4b4b4[Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4]Tb4b4b4;
Te6edf3snprintfTb4b4b4(Te6edf3packet_cache_pathTb4b4b4, Te6edf3TypeTff7b72:Tff7b72:Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3FILEPATH_MAXSIZETb4b4b4, Ta5d6ff"Ta5d6ff%s/%sTa5d6ff"Tb4b4b4, Te6edf3ReticulumTff7b72:Tff7b72:Te6edf3_cachepathTb4b4b4, Te6edf3fileTb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3OSTff7b72:Tff7b72:Te6edf3remove_fileTb4b4b4(Te6edf3packet_cache_pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3clear_caches_in_memoryTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::clear_caches_in_memory()Ta5d6ff"Tb4b4b4)Tb4b4b4;
T8b949e// Clear the packet hashlist (duplicate detection, ~100 × 40 bytes = ~4KB)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_packet_hashlistTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3before Tff7b72= Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_packet_hashlistTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::clear_caches_in_memory: cleared %d packet hashlist entriesTa5d6ff"Tb4b4b4, Te6edf3beforeTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Clear global anti-replay blobs (capped at 8 × ~80 bytes = ~640 bytes)
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_global_blobsTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3before Tff7b72= Te6edf3_global_blobsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_global_blobsTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::clear_caches_in_memory: cleared %d global blobsTa5d6ff"Tb4b4b4, Te6edf3beforeTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Clear announce rate table
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_announce_rate_tableTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3before Tff7b72= Te6edf3_announce_rate_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_announce_rate_tableTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::clear_caches_in_memory: cleared %d announce rate entriesTa5d6ff"Tb4b4b4, Te6edf3beforeTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Clear discovery path request tags
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657size_t Te6edf3before Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DEBUGFTb4b4b4(Ta5d6ff"Ta5d6ffTransport::clear_caches_in_memory: cleared %d discovery PR tagsTa5d6ff"Tb4b4b4, Te6edf3beforeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3cull_path_tableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3dump_statsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3OSTff7b72:Tff7b72:Te6edf3dump_heap_statsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3mem_used Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657size_t Te6edf3flash_used Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_sizeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_availableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3_last_memory Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_last_memory Tff7b72= Te6edf3mem_usedTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_last_flash Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_last_flash Tff7b72= Te6edf3flash_usedTb4b4b4;
Tb4b4b4}
T8b949e// memory
T8b949e// storage
T8b949e// _destinations
T8b949e// _destination_table
T8b949e// _reverse_table
T8b949e// _announce_table
T8b949e// _held_announces
Te6edf3HEADFTb4b4b4(Te6edf3LOG_VERBOSETb4b4b4, Ta5d6ff"Ta5d6ffheap: %u/%u (%u%%) [%+d] flash: %u/%u (%u%%) [%+d] paths: %u dsts: %u revr: %u annc: %u held: %uTa5d6ff"Tb4b4b4, Te6edf3mem_usedTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3mem_used Tff7b72/ Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3OSTff7b72:Tff7b72:Te6edf3heap_sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff100.0Tb4b4b4)Tb4b4b4, Te6edf3mem_used Tff7b72- Te6edf3_last_memoryTb4b4b4, Te6edf3flash_usedTb4b4b4, Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Tb4b4b4(Tffa657intTb4b4b4)Tb4b4b4(Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3flash_used Tff7b72/ Tb4b4b4(Tffa657doubleTb4b4b4)Te6edf3OSTff7b72:Tff7b72:Te6edf3storage_sizeTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff100.0Tb4b4b4)Tb4b4b4, Te6edf3flash_used Tff7b72- Te6edf3_last_flashTb4b4b4, Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_reverse_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_announce_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_held_announcesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// _path_requests
T8b949e// _discovery_path_requests
T8b949e// _pending_local_path_requests
T8b949e// _discovery_pr_tags
T8b949e// _control_destinations
T8b949e// _control_hashes
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffpreqs: %u dpreqs: %u ppreqs: %u dprt: %u cdsts: %u chshs: %uTa5d6ff"Tb4b4b4, Te6edf3_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_discovery_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_pending_local_path_requestsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_control_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_control_hashesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
T8b949e// _packet_hashlist
T8b949e// _receipts
T8b949e// _link_table
T8b949e// _pending_links
T8b949e// _active_links
T8b949e// _tunnels
Tffa657uint32_t Te6edf3destination_path_responses Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3destination_hashTb4b4b4, Te6edf3destinationTb4b4b4] Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Te6edf3destination_path_responses Tff7b72+Tff7b72= Te6edf3destinationTb4b4b4.Te6edf3path_responsesTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint32_t Te6edf3interface_announces Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3interface_hashTb4b4b4, Te6edf3interfaceTb4b4b4] Tff7b72: Te6edf3_interfacesTb4b4b4) Tb4b4b4{
Te6edf3interface_announces Tff7b72+Tff7b72= Te6edf3interfaceTb4b4b4.Te6edf3announce_queueTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffphl: %u rcp: %u lt: %u pl: %u al: %u tun: %uTa5d6ff"Tb4b4b4, Te6edf3_packet_hashlistTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_receiptsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_link_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_pending_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_active_linksTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_tunnelsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffbla: %u bma: %uTa5d6ff"Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3VERBOSEFTb4b4b4(Ta5d6ff"Ta5d6ffpin: %u pout: %u padd: %u dpr: %u ikd: %u ia: %uTffea00\rTffea00\nTa5d6ff"Tb4b4b4, Te6edf3_packets_receivedTb4b4b4, Te6edf3_packets_sentTb4b4b4, Te6edf3_destinations_addedTb4b4b4, Te6edf3destination_path_responsesTb4b4b4, Te6edf3IdentityTff7b72:Tff7b72:Te6edf3_known_destinationsTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3interface_announcesTb4b4b4)Tb4b4b4;
Te6edf3_last_memory Tff7b72= Te6edf3mem_usedTb4b4b4;
Te6edf3_last_flash Tff7b72= Te6edf3flash_usedTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3dump_whitelistsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72ifdef FIREWALL_MODE
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff[WL#1] %u entries:Ta5d6ff"Tb4b4b4, Te6edf3_firewall_local_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3addr Tff7b72: Te6edf3_firewall_local_addressesTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff %sTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Tffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff[WL#2] %u entries:Ta5d6ff"Tb4b4b4, Te6edf3_firewall_mentioned_addressesTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Te6edf3addr Tff7b72: Te6edf3_firewall_mentioned_addressesTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff %sTa5d6ff"Tb4b4b4, Te6edf3addrTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3substrTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff8Tb4b4b4)Tb4b4b4.Te6edf3c_strTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Tffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3exit_handlerTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::exit_handler()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_ownerTb4b4b4.Te6edf3is_connected_to_shared_instanceTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3persist_dataTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Te6edf3Destination Te6edf3TransportTff7b72:Tff7b72:Te6edf3find_destination_from_hashTb4b4b4(Tff7b72const Te6edf3BytesTff7b72& Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Searching for destination Ta5d6ff" Tff7b72+ Te6edf3destination_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(DESTINATIONS_SET)
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3DestinationTff7b72& Te6edf3destination Tff7b72: Te6edf3_destinationsTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destinationTb4b4b4.Te6edf3get_hashTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Found destination Ta5d6ff" Tff7b72+ Te6edf3destinationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3destinationTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72elif defined(DESTINATIONS_MAP)
Tff7b72auto Te6edf3iter Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3findTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3iter Tff7b72!Tff7b72= Te6edf3_destinationsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::find_destination_from_hash: Found destination Ta5d6ff" Tff7b72+ Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4(Tff7b72*Te6edf3iterTb4b4b4)Tb4b4b4.Te6edf3secondTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72return Tb4b4b4{Te6edf3TypeTff7b72:Tff7b72:Te6edf3NONETb4b4b4}Tb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657void Te6edf3TransportTff7b72:Tff7b72:Te6edf3cull_path_tableTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table()Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657double Te6edf3now Tff7b72= Te6edf3OSTff7b72:Tff7b72:Te6edf3timeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Pass 1: Remove individual expired entries from each deque
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72> Te6edf3empty_destsTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3dest_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Te6edf3dequeTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3stdTff7b72:Tff7b72:Te6edf3remove_ifTb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Te6edf3nowTb4b4b4]Tb4b4b4(Tff7b72const Te6edf3PathEntryTff7b72& Te6edf3eTb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3eTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4,
Te6edf3dequeTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3dequeTb4b4b4.Te6edf3emptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3empty_destsTb4b4b4.Te6edf3push_backTb4b4b4(Te6edf3dest_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// Remove empty destination entries
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3dest_hash Tff7b72: Te6edf3empty_destsTb4b4b4) Tb4b4b4{
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3dest_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// Pass 2: If still over maxsize, evict destinations with the lowest-score best path
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72> Te6edf3_path_table_maxsizeTb4b4b4) Tb4b4b4{
T8b949e// Build sorted list: (dest_hash, best_score) ascending
Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72> Te6edf3scoredTb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72autoTff7b72& Tb4b4b4[Te6edf3dest_hashTb4b4b4, Te6edf3dequeTb4b4b4] Tff7b72: Te6edf3_destination_tableTb4b4b4) Tb4b4b4{
Tffa657double Te6edf3best_score Tff7b72= T79c0ff-1.0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3entry Tff7b72: Te6edf3dequeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3entryTb4b4b4.Te6edf3is_expiredTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;
Te6edf3Interface Te6edf3iface Tff7b72= Te6edf3find_interface_from_hashTb4b4b4(Te6edf3entryTb4b4b4.Te6edf3receiving_interfaceTb4b4b4)Tb4b4b4;
Tffa657double Te6edf3s Tff7b72= Te6edf3entryTb4b4b4.Te6edf3scoreTb4b4b4(Te6edf3iface Tff7b72? Te6edf3ifaceTb4b4b4.Te6edf3bitrateTb4b4b4(Tb4b4b4) Tff7b72: T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3s Tff7b72> Te6edf3best_scoreTb4b4b4) Te6edf3best_score Tff7b72= Te6edf3sTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3best_score Tff7b72< T79c0ff0Tb4b4b4) Te6edf3best_score Tff7b72= T79c0ff0Tb4b4b4; T8b949e// all expired, score 0
Te6edf3scoredTb4b4b4.Te6edf3push_backTb4b4b4(Tb4b4b4{Te6edf3dest_hashTb4b4b4, Te6edf3best_scoreTb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3stdTff7b72:Tff7b72:Te6edf3sortTb4b4b4(Te6edf3scoredTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3scoredTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4[Tb4b4b4]Tb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72& Te6edf3aTb4b4b4, Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3pairTff7b72<Te6edf3BytesTb4b4b4, Tffa657doubleTff7b72>Tff7b72& Te6edf3bTb4b4b4) Tb4b4b4{ Tff7b72return Te6edf3aTb4b4b4.Te6edf3second Tff7b72< Te6edf3bTb4b4b4.Te6edf3secondTb4b4b4; Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Tb4b4b4[Te6edf3dest_hashTb4b4b4, Te6edf3scoreTb4b4b4] Tff7b72: Te6edf3scoredTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_destination_tableTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72<Tff7b72= Te6edf3_path_table_maxsizeTb4b4b4) Tff7b72breakTb4b4b4;
Te6edf3TRACETb4b4b4(Ta5d6ff"Ta5d6ffTransport::cull_path_table: Removing destination Ta5d6ff" Tff7b72+ Te6edf3dest_hashTb4b4b4.Te6edf3toHexTb4b4b4(Tb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff from path table (score=Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3scoreTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_destination_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3dest_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3DEBUGTb4b4b4(Ta5d6ff"Ta5d6ffRemoved Ta5d6ff" Tff7b72+ Te6edf3stdTff7b72:Tff7b72:Te6edf3to_stringTb4b4b4(Te6edf3countTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff path(s) from path tableTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_reverse_entriesTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3truncated_packet_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_reverse_tableTb4b4b4, Te6edf3truncated_packet_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u reverse table entriesTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_linksTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3link_id Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_link_tableTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u linksTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_pathsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
T8b949e//_destination_table.erase(destination_hash);
Te6edf3remove_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u pathsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_discovery_path_requestsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3destination_hash Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3flatmap_eraseTb4b4b4(Te6edf3_discovery_path_requestsTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
T8b949e// Also clean up _discovery_pr_tags so future path requests
T8b949e// for this destination are not permanently suppressed.
T8b949e// unique_tag = destination_hash (16B) + tag_bytes (1-16B)
Tff7b72for Tb4b4b4(Tff7b72auto Te6edf3it Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3it Tff7b72!Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3endTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3itTff7b72-Tff7b72>Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3destination_hashTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3itTff7b72-Tff7b72>Te6edf3leftTb4b4b4(Te6edf3destination_hashTb4b4b4.Te6edf3sizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= Te6edf3destination_hashTb4b4b4) Tb4b4b4{
Te6edf3it Tff7b72= Te6edf3_discovery_pr_tagsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3itTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72+Tff7b72+Te6edf3itTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u waiting path requestsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
T8b949e/*static*/ Tffa657uint16_t Te6edf3TransportTff7b72:Tff7b72:Te6edf3remove_tunnelsTb4b4b4(Tff7b72const Te6edf3stdTff7b72:Tff7b72:Te6edf3vectorTff7b72<Te6edf3BytesTff7b72>Tff7b72& Te6edf3hashesTb4b4b4) Tb4b4b4{
Tffa657uint16_t Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tff7b72autoTff7b72& Te6edf3tunnel_id Tff7b72: Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3_tunnelsTb4b4b4.Te6edf3eraseTb4b4b4(Te6edf3tunnel_idTb4b4b4)Tb4b4b4;
Tff7b72+Tff7b72+Te6edf3countTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3TRACEFTb4b4b4(Ta5d6ff"Ta5d6ffReleased %u tunnelsTa5d6ff"Tb4b4b4, Te6edf3countTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3countTb4b4b4;
Tb4b4b4}
Served by rngit 1.4.2 - Generated in 0.44s